- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have these C & C++ routines that I want to compile into my dll. I have no clue about C and all the examples I have in the literature show how to call Fortran from C and not the other way around. Help!
I intend on compiling these routines into my dll - they are from the generic.xll example for making native Excel addins. Any hints?
I have these C & C++ routines that I want to compile into my dll. I have no clue about C and all the examples I have in the literature show how to call Fortran from C and not the other way around. Help!
I intend on compiling these routines into my dll - they are from the generic.xll example for making native Excel addins. Any hints?
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are many ways -- I'll explain the one I typically use. I'll assume Visual C++ on the C side; with other compilers dllexport directives are different.
All C functions should have the following prototype (stated in both .h and .cpp) file. Typically, this is done using a #define:
Next, on the Fortran side, create interface blocks (in include file or, better, in a module) using the following rules:
- Void->SUBROUTINE, other->FUNCTION
- All routines should have
- All routines should have ALIAS. Mangled name begins with underscore,
it's case-sensitive and ends with @ plus no. of arguments x 4. You can use command-line tool
- Pointer (*) or reference (&) arguments should have
Here's a small example:
Don't forget to add MyDll.lib to your Fortran project (just as any source file).
HTH
Jugoslav
All C functions should have the following prototype (stated in both .h and .cpp) file. Typically, this is done using a #define:
#define MYAPI extern "C" __declspec(dllexport) // Only in .h file MYAPI int/void/whatever __stdcall CFunc() //In both .h and .cpp file
Next, on the Fortran side, create interface blocks (in include file or, better, in a module) using the following rules:
- Void->SUBROUTINE, other->FUNCTION
- All routines should have
!DEC$ATTRIBUTES STDCALL, DLLIMPORT
- All routines should have ALIAS. Mangled name begins with underscore,
it's case-sensitive and ends with @ plus no. of arguments x 4. You can use command-line tool
dumpbin /exports mydll.dll
to see exact mangled name. - Pointer (*) or reference (&) arguments should have
!DEC$ATTRIBUTES REFERENCE
. Frequently, in apis there's a #define somewhere for pointers-to-something starting with LP (e.g. LPCTSTR is pointer-to-string) Here's a small example:
MyDll.h==8<=============== #define MYAPI extern "C" __declspec(dllexport) MYAPI int GetAString(int i, char* szString) MyDll.cpp==8<=============== #include MyDll.h MYAPI int GetAString(int i, char* pszString) { sprintf(pszString. "%5d", i); //Equal to Fortran internal WRITE return 10; } Interfaces.f90==8<=============== MODULE INTERFACES INTERFACE INTEGER FUNCTION GetAString(i, s) !DEC$ATTRIBUTES STDCALL, DLLIMPORT, ALIAS: "_GetAString@8":: GetAString INTEGER:: i !DEC$ATTRIBUTES REFERENCE:: s CHARACTER(*):: s END FUNCTION END INTERFACE END MODULE INTERFACES Code.f90==8<=============== USE INTERFACES CHARACTER(20):: sTemp j = GetAString(15, sTemp) WRITE(*,*) sTemp
Don't forget to add MyDll.lib to your Fortran project (just as any source file).
HTH
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a follow-up question:
What if the c code is in a DLL developed by a third party and the location of that DLL will only be known when my CVF executable is installed in the user's computer? In other words, how to specify the location of that DLL at runtime?
Is it sufficient to have the DLL somewhere in the command path? Are there any (more elegant and robust) alternatives to the command path?
Thanks,
Gabriel
What if the c code is in a DLL developed by a third party and the location of that DLL will only be known when my CVF executable is installed in the user's computer? In other words, how to specify the location of that DLL at runtime?
Is it sufficient to have the DLL somewhere in the command path? Are there any (more elegant and robust) alternatives to the command path?
Thanks,
Gabriel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See for example LoadLibrary entry in platform SDK help for description on order of how Windows determines which library to load. Actually, it would be a good idea to read entire Windows Base Services/Executables/Dynamic-link libraries chapter. In short, when using "Load-time dynamic linking" method (i.e. including .lib into your project), you can't determine the path from which the dll will be loaded -- it's determined by Windows as described in LoadLibrary. If that's not OK for you,
you might resort to "Run-time binding", i.e. using LoadLibrary instead of .lib file.
Then, the changes in my sample would be:
- omit ALIAS and DLLIMPORT directives in INTERFACE;
- add
- use the following piece of code to call:
Call FreeLibrary(hLibrary) when you don't need the dll anymore. Also, you can call GetProcAddress only once (it determines function's address) and call GetAString as many times as you want afterwards.
Jugoslav
you might resort to "Run-time binding", i.e. using LoadLibrary instead of .lib file.
Then, the changes in my sample would be:
- omit ALIAS and DLLIMPORT directives in INTERFACE;
- add
POINTER(pGetAString, GetAString)
statement immediately after INTERFACE block;- use the following piece of code to call:
hLibrary = LoadLibrary("C:SomewhereSome.dll"//CHAR(0)) IF (hLibrary .NE. 0) THEN !DLL exists pGetAString = GetProcAddress(hLibrary, "_GetAString@8"C) IF (pGetAString .NE. 0) THEN !It does export GetAString function j = GetAString(15, sTemp) END IF END IF
Call FreeLibrary(hLibrary) when you don't need the dll anymore. Also, you can call GetProcAddress only once (it determines function's address) and call GetAString as many times as you want afterwards.
Jugoslav

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page