- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good Day,
We are a converting our Ocean Science suite of applications from Compaq Visual Fortran with
Visual C v6 to Intel Fortran with Visual Studio 2005 and are having some difficulty.
As a test I created a Fortran DLL project, and a C++ MFC DLL Project all in the same VS solution
TEST1 - works great
In the Fortran project I defined a Fortran function as available for export and this works fine
We have a separate C# solution that can call this just fine.
real function SquareRoot(myNumber)
!DEC$ ATTRIBUTES DLLEXPORT::SquareRoot
!DEC$ ATTRIBUTES ALIAS:'SquareRoot'::SquareRoot
!DEC$ ATTRIBUTES VALUE :: myNumber
REAL, INTENT(IN) :: myNumber
REAL mySquareRoot
mySquareRoot = SQRT(myNumber)
SquareRoot = mySquareRoot
end function SquareRoot
TEST2 - Linking Error
We have several Fortran programs that call C++ code so we tested this as follows
1.Create a simply c++ program
// Lets try and write a simple program now that fortran can call
// Firstly we must declare it to be an external C function
extern "C" __declspec(dllexport) int GetRandomInteger();
// Really simple - give us a number
int GetRandomInteger()
{
return 25;
}
2. I ran dumpbin to be sure the function was available for export
Dump of file testmfcdll.dll
File Type: DLL
Section contains the following exports for TestMFCDLL.dll
00000000 characteristics
4A424584 time date stamp Wed Jun 24 08:25:56 2009
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001050 GetRandomInteger = _GetRandomInteger
Summary
1000 .data
1000 .rdata
1000 .reloc
1000 .rsrc
2000 .text
3. I created a fortran function as follows in the fortran dll project
INTEGER FUNCTION GetNumberFromCPP()
INTERFACE TO FUNCTION GetRandomInteger()
!DEC$ ATTRIBUTES C, DLLIMPORT, DECORATE, ALIAS:'_GetRandomInteger'::GetRandomInteger
INTEGER GetRandomInteger
END
GetNumberFromCPP = GetRandomInteger()
END FUNCTION GetNumberFromCPP
When I compile the fortran dll project i get the dreaded LNK2019 error as follows:
error LNK2019: unresolved external symbol __imp___GetRandomInteger referenced
in function _GETNUMBERFROMCPP
NOTES:
I have tried the !DEC$ with and without "C","DECORATE","DLLIMPORT"
I have tried adding the lib file from the c++ dll to the fortran source directory
I have changed the name in the alias with/without "_"
I am a newby to fortran and c++ so I may have missed something very simple.
I appreciate any help ... Thanks Mike
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!DEC$ ATTRIBUTES STDCALL, DLLIMPORT, ALIAS:'_GetRandomInteger'::GetRandomInteger
I know you said you did, but could you try this one again please?
!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:'_GetRandomInteger'::GetRandomInteger
The aboveshould work too, and might be better. I worry what other side effects you might have by declaring the routine as STDCALL instead of C. There are calling-standard differences there that might bite you.
In your original version, the "DECORATE" put an extra underscore before the alias name, giving the three-underscores in the middle of the external name.
- Lorri
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!DEC$ ATTRIBUTES STDCALL, DLLIMPORT, ALIAS:'_GetRandomInteger'::GetRandomInteger
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!DEC$ ATTRIBUTES STDCALL, DLLIMPORT, ALIAS:'_GetRandomInteger'::GetRandomInteger
I know you said you did, but could you try this one again please?
!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:'_GetRandomInteger'::GetRandomInteger
The aboveshould work too, and might be better. I worry what other side effects you might have by declaring the routine as STDCALL instead of C. There are calling-standard differences there that might bite you.
In your original version, the "DECORATE" put an extra underscore before the alias name, giving the three-underscores in the middle of the external name.
- Lorri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know you said you did, but could you try this one again please?
!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:'_GetRandomInteger'::GetRandomInteger
The aboveshould work too, and might be better. I worry what other side effects you might have by declaring the routine as STDCALL instead of C. There are calling-standard differences there that might bite you.
In your original version, the "DECORATE" put an extra underscore before the alias name, giving the three-underscores in the middle of the external name.
- Lorri
I tried the same example, but getting some link errors.
C++ dll:
.cpp file
#include"attempt1.h"
// Really simple - give us a number
int __stdcall GetRandomInteger()
{
return 25;
}
.h file
extern "C" int __stdcall GetRandomInteger();
.def file
LIBRARY "Attempt"
;CODE PRELOAD MOVEABLE DISCARDABLE
;DATA PRELOAD MOVEABLE SINGLE
;HEAPSIZE 1024
EXPORTS
GetRandomInteger
Fortran dll: .lib file of above C++ was added as resource file in this project
.f file
FUNCTION GetNumberFromCPP()
INTERFACE to FUNCTION GetRandomInteger()
!DEC$ ATTRIBUTES C, DLLIMPORT, ALIAS:'_GetRandomInteger'::GetRandomInteger
Integer GetRandomInteger
END
Integer GetNumberFromCPP
GetNumberFromCPP = GetRandomInteger()
END FUNCTION GetNumberFromCPP
Error:
error LNK2019: unresolved external symbol _getrandominteger@0 referenced in function _getnumberfromcpp
1>DebugConnect.dll : fatal error LNK1120: 1 unresolved externals
Please help me as i am new to this interface.
Regards,
Jayaraj
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. In C++ (I am using Microsoft VS 2008), I have
[cpp]extern "C" { __declspec(dllexport) int __stdcall InitSignalProcessing( void ); } __declspec(dllexport) int __stdcall InitSignalProcessing( void ) { return (int) SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ); }[/cpp]Please note that you are probably missing __declspec(dllexport) in your code. The .def file seems OK.
2. In Fortran, I have
[cpp]interfaceNote that there is no leading underscore in alias:"InitSignalProcessing" :: InitSignalProcessing.
integer*4 function InitSignalProcessing ( ) !dec$ attributes stdcall, dllimport, decorate, alias: "InitSignalProcessing" :: InitSignalProcessing end function
end interface[/cpp]
I have a console application in Fortran, not a dll, so I am adding the .lib file into the additional dependencies of the linker (/IMPLIB: myDll.lib). It might be interesting for you that I am using the C++ dll as delay-loaded (/DELAYLOAD: "myDll.dll").
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. In C++ (I am using Microsoft VS 2008), I have
[cpp]extern "C" {Please note that you are probably missing __declspec(dllexport) in your code. The .def file seems OK.
__declspec(dllexport) int __stdcall InitSignalProcessing( void );
}
__declspec(dllexport) int __stdcall InitSignalProcessing( void )
{
return (int) SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE );
}[/cpp]
2. In Fortran, I have
[cpp]interfaceNote that there is no leading underscore in alias:"InitSignalProcessing" :: InitSignalProcessing.
integer*4 function InitSignalProcessing ( )
!dec$ attributes stdcall, dllimport, decorate, alias: "InitSignalProcessing" :: InitSignalProcessing
end function
end interface[/cpp]
I have a console application in Fortran, not a dll, so I am adding the .lib file into the additional dependencies of the linker (/IMPLIB: myDll.lib). It might be interesting for you that I am using the C++ dll as delay-loaded (/DELAYLOAD: "myDll.dll").
Hi Jirina,
could you please explain how to do same thing with ISO_C_BINDING module?
I tried i am getting linker error saying that function is undefined.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Non-defaultish things:
- The C++ program was a C++ empty project that had its General > Configuration type changed to be a DLL.
- The fortran program's General > Output directory is set to be the solution's output directory (so the DLL and exe end up in the same place).
- The fortran program's Libraries > Runtime library is set to be the DLL flavour (so we don't end up with multiple runtimes).
- The Fortran project's "Project Dependencies" include the C++ project.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Non-defaultish things:
- The C++ program was a C++ empty project that had its General > Configuration type changed to be a DLL.
- The fortran program's General > Output directory is set to be the solution's output directory (so the DLL and exe end up in the same place).
- The fortran program's Libraries > Runtime library is set to be the DLL flavour (so we don't end up with multiple runtimes).
- The Fortran project's "Project Dependencies" include the C++ project.
How to do if c function defined with STDCALL. as we know most of the c libraries shipped with STDCALL
if i added __stdcal to C function in your samples
extern "C" int __declspec(dllexport) __stdcall a_function(double arg)
I am getting following error
2>Compiling with Intel Visual Fortran 11.1.038 [IA-32]...
2>FortranToCppDLL.f90
2>Linking...
2>FortranToCppDLL.obj : error LNK2019: unresolved external symbol _a_function referenced in function _MAIN__
2>C:Documents and SettingsAdministratorDesktopFortranToCppDLLDebugFortranProgram.exe : fatal error LNK1120: 1 unresolved externals
could anybody please explain how to do this with BIND(C)?
I am using Visual fortran 11.1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have to use preprocessor flags inoder to work with both intel and gfortran compilers.
Thank you for all
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page