Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29265 Discussions

Newbie Question - Calling a Fortrn DLL from a Fortran EXE in .NET

aggiedad
Beginner
1,074 Views

Hi all,

I am using VS2003 and would like to create a simple fortran .exe that will call a subroutine in a Fortran DLL.

I have looked at the examples but didn't find one that matched my needs. I have tried a number of things

!dec$ attributes dllexport, stdcall, reference, alias : "subtest1" :: subtest1

dll.load("c:\data\fortran\subtest", symbol ="subtest1"

but cannot seem to find the correct combination and syntax.

Is there a quick and dirty VS solution example that someone could pass on to me?

Thank you,

Eric

0 Kudos
13 Replies
Steven_L_Intel1
Employee
1,074 Views
To call a Fortran DLL routine from Fortran, you don't need anything special in the source. Just link to the export library created when the DLL is built. You do need to use !DEC$ ATTRIBUTES DLLEXPORT :: routinename in the DLL routine itself. You don't need STDCALL or ALIAS or REFERENCE unless you're doing something out of the ordinary.
0 Kudos
aggiedad
Beginner
1,074 Views

Thanks for your help Steve. I got it to work using the following steps. However, I am sure there is a better way.

Created a new Fortran - Windows Application project

File > New > Project > Intel Fortran Projects > Windows Application, changing the name to F2F and the location to C:Test

When the wizard box is displayed I click on Application Settings and make sure Dialog-based sample code is selected. Then click Finish

This creates the project (and solution) and inserts a basic form and command button example. Click on the Start arrow to build and run the project. It displays a form with two buttons. Then click Exit.

I then created another projectFile > New > Project > Intel Fortran Projects > Dynamic-link Library, using the same location as the Windows Application and F2Fdll as the name.

When the wizard box is displayed I click on Dll Settingsand make sure Dll_sample code with export routineis selected. Then click Finish

The wizard adds the !DEC$ ATTRIBUTES DLLEXPORT::F2Fdll line for me.

Then I select the project (F2Fdll) in Solution Explorer then click on Project > Properties > Linker > General > Output Fileand enter the path and filenamewhere I want the output DLL file to be placed each time it is compiled (C:TestF2FDebugF2Fdll.dll). I did this because of an error I got after clicking Start telling me it could not find itthe F2Fdll.dll file. I probably could have changes something elsethat would work better but this got me on the right path.

I select the project (F2F) in Solution Explorer then click on Project > Properties > Linker > Input > Additional Dependancies I entered thepath and filenamewhere the library file is located (C:TestF2FDllDebugF2FDll.lib)

Finally, I selected the Solution F2F in Solution Explorer then click on Project > Properties > Project Dependencies and checked theF2F box.

Ithen replaced the F2Fdll subroutine with a simple set of code

subroutine

F2Fdll(y,z)

! Expose subroutine F2Fdll to users of this DLL

!

!DEC$ ATTRIBUTES DLLEXPORT::F2Fdll

! Variables

! Body of F2Fdll

INTEGER y, z

REAL x(y)

IF( y .gt. 1)THEN

x(1) = 23

DO 10 i=2,y

x(i) = z*x(i-1)+x(i)

10 CONTINUE

ENDIF

RETURN

end subroutine

F2Fdll

And replaced the F2FApply subroutine in the F2F executablewith

SUBROUTINE

F2FApply( dlg, id, callbacktype )

!DEC$ ATTRIBUTES DEFAULT :: F2FApply

! use iflogm

!

! implicit none

!

! type (dialog) dlg

! integer id, callbacktype

!

! if (callbacktype == dlg_clicked) then

! ! TO DO; Add your APPLY logic here

! endif

call F2FDll(5, 6)

END SUBROUTINE F2FApply

I set a breakpoint on the call line and started the application.

Clicked on the Apply button and used the F11 (step) key to enter the dll and loop through the code. I also placed the variable x in the Watch window to see it working.

Now I need to work on extending it further. Additional comments are welcome and appreciated.

Thanks again Steve.

Eric

0 Kudos
aggiedad
Beginner
1,074 Views

Hi all, I am finally back looking at my code again. The problem we solved above was using a QuickWin solution. I am now attempting to call a Fortran DLL from a Fortran (console) application. I am still currentlyusing Visual Studio 2003 to write, compile and test this project. I have two projects (EXESide and DLLSide) in the same solution.

I am having trouble getting the console application to recognize or "see" the Fortran DLL. I am getting an error

Error: Error in opening the Library module file. [DLLSIDE]

I have tried a number of things working with the EXE's and DLL's properties (Fortran, Linker, etc.) I placed then lib filename in the Linker Dependencies, placed the DLL in the EXE debug folder, and much more, but have not got the EXE to recognize the DLL.

Console Application

program EXESide

use DLLSide
implicit none

end program EXESide

A module in the DLL project

module DLLSide

!DEC$ ATTRIBUTES DLLEXPORT::DLLSide
use IFNLS,only: NLSFormatDate,NLSFormatTime,NLS$LongDate

end module DLLSide

I'm thinking I need to add the location of the DLL or Lib file in a property for the EXE or possibly in the path section of the operating system but have exhausted all my options.

Can someone please help?

Thanks!

Eric

0 Kudos
Steven_L_Intel1
Employee
1,074 Views
That error has nothing to do with DLLs. It's simply saying that the compiler can't find dllside.mod, the module file created by compiling module DLLSIDE. By default, it looks in the same directory as the source file containing the USE statement, and also in directories listed in the INCLUDE path.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,074 Views
By the way, Steve, I just now realized that the error message text:
Error opening Library module file 
is fairly misleading (although it's been around for years): .mod files have little or nothing to do with "libraries" in the most common sense of the word (static library or dynamic link library).
I suggest rephrasing it, or at least removing the word "library".
0 Kudos
Steven_L_Intel1
Employee
1,074 Views
Yes, I have felt the same about that message. I'll see what can be done.
0 Kudos
aggiedad
Beginner
1,074 Views

Thanks Steve,

I added the path (.mod files location) to the properties section of the exe application in the Fortran General Additional Include Directories and I got past that problem.

--------------------------------------

I have an additional issue now.

I would like to use the same Fortran DLL for both my C# and Fortran console applications. In one of my dll modules I have the following three declarations.

subroutine set_flags(data_flag,diagnostics_flag)

!DEC$ ATTRIBUTES DLLEXPORT::set_flags

!DEC$ ATTRIBUTES ALIAS:'_set_flags'::set_flags

!DEC$ ATTRIBUTES VALUE::data_flag,diagnostics_flag

! Code here

end subroutine set_flags

This works when the C# code calls the DLL. But I get an error when the Fortran calls it.

If I comment out the middle DEC statement (Alias) then the Fortran calls it successfully but the C# code fails.

Any thoughts on how I can get around this?

Thanks,

Eric

0 Kudos
Steven_L_Intel1
Employee
1,073 Views

You will need the ALIAS to be visible to the Fortran caller. I think, though, that you also need:

!DEC$ ATTRIBUTES STDCALL, REFERENCE :: set_flags

or else you'll get stack corruption when called from C#. I'm not 100% certain of that. The Fortran caller needs to see this too. An INTERFACE block is the easiest way to specify this.

0 Kudos
aggiedad
Beginner
1,074 Views

Thanks Steve,

I added the STDCALL to both applications.I stillhave to comment out the Alias line when calling from the Fortran exe. When I do the code steps right in. But if uncomment the line I get the following error.

Unhandled exception at 0x400025ff in exeside.exe: 0xC0000005: Access violation reading location 0x400025ff.

I am not sure what an INTERFACE BLOCK is but I will look it up.

Eric

0 Kudos
Steven_L_Intel1
Employee
1,074 Views
I don't quite understand your last post, Eric. Uncomment which line? From where does the acces sviolation occur? As I mentioned, the Fortran caller needs to see that the routine is given a different name.
0 Kudos
aggiedad
Beginner
1,074 Views

Sorry for the confusion.

Currently I have the two projects. One is the C# calling the Fortran DLL and the other is a Fortran console app that will eventually call the same Fortran DLL but is currently using its own version (copy) of the DLL code.

I added the STDCALL you suggested above to both versions of the DLL. I did not get any error, but it didnt solve my problem.

I have the following lines in the DLL version of the Fortran console application

!DEC$ ATTRIBUTES DLLEXPORT::set_flags

!DEC$ ATTRIBUTES ALIAS:'_set_flags'::set_flags

!DEC$ ATTRIBUTES STDCALL, REFERENCE :: set_flags

!DEC$ ATTRIBUTES VALUE:: data_flag,diagnostics_flag

When I get to the call set_flags line of code in the console (exeside.exe) application an error occurs.

Unhandled exception at 0x400025ff in exeside.exe: 0xC0000005: Access violation reading location 0x400025ff.

If I comment out the !!DEC$ ATTRIBUTES ALIAS:'_set_flags'::set_flags line then the console application steps into the DLL and runs the code.

On the C# exe side, calling the Fortran DLL, I have the same 4 DEC statements and it works.

However, when I comment out the same line of code

!!DEC$ ATTRIBUTES ALIAS:'_set_flags'::set_flags

in the C# version of the Fortran DLL I get the error

Unable to find an entry point named set_flags in DLL DLLSide.dll.

In other words I need the Alias DEC statement when calling from the C# code and I dont need it (or cant have it) on the Fortran console application calling the DLL.

Any ideas on how to get both exes to work with the same set of DEC statements? Is there a better or different way?

Thanks a bunch for your help,

Eric

0 Kudos
Steven_L_Intel1
Employee
1,074 Views

At this point I'd ask that you submit an issue to Intel Premier Support, attach a ZIP of the projects along with instructions for reprodiucing the problem, and let us look at it. Please request that the issue be assigned to Steve Lionel.

0 Kudos
aggiedad
Beginner
1,073 Views

Hi Steve,

Thanks for the help. I just wanted to add the resolution to this issue so others might benefit.

My problem was that my currentFortran version was 9.0 and needed to upgrade to 9.1.

If you attempt this once VS is loaded then search this site for the steps that Steve has written to help in the process.

Thanks again,

Eric

0 Kudos
Reply