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

Trouble with a Fortran DLL called from C#

mountain_ike1
初學者
2,798 檢視
I am trying to call a Fortran DLL from a C# program. I have successfully accomplished that with a simple program. and I have seen data passed back and forth between the program and my test DLL. However, when I add complex (and uncalled) subroutines to my test DLL, I get an 'Additional information: An attempt was made to load a program with an incorrect format.' exception. The complex subroutines have worked as part of a compiled Fortran program and they compile just fine in the DLL. Is there some switch I am missing? I am using VS2005 and the Intel Fortran Compiler 9.1.3192.2005. Help!!!
0 積分
17 回應
ArturGuzik
傑出貢獻者 I
2,798 檢視
Quoting - mountain_ike
'Additional information: An attempt was made to load a program with an incorrect format.' exception.

Hi,

is this the 'System.BadImageFormatException'? Do you build and run dll on the same platform? I mean 32/64-bit? (usually you can get this kind of exception if you build dll on 32-bit and move the code to 64-bit, C# rebuilds while dll doesn't). More info is required, I'm afraid.

A.
mountain_ike1
初學者
2,798 檢視
Quoting - ArturGuzik

Hi,

is this the 'System.BadImageFormatException'? Do you build and run dll on the same platform? I mean 32/64-bit? (usually you can get this kind of exception if you build dll on 32-bit and move the code to 64-bit, C# rebuilds while dll doesn't). More info is required, I'm afraid.

A.
This is the System.BadImageFormatException. I had read about the 32/64 issue, but for this project I am building both the Fortran DLL and the C# application as part of the same solution, all on a 32-bit computer. I have access to all of the Fortran source code so this is no problem, and actually a convinient way to develop my application.
ArturGuzik
傑出貢獻者 I
2,798 檢視
OK then. I understand that you went through standard steps: (1) checking exports using dumpbin (2) checking dependencies using Dependency Walker (3) trying link without Library Dependencies (4) verifying that you have not specified something (strange) in Additional Dependencies (linker Input).

Does the dll work if called from Fortran exe?

A.
mountain_ike1
初學者
2,798 檢視
Quoting - ArturGuzik
OK then. I understand that you went through standard steps: (1) checking exports using dumpbin (2) checking dependencies using Dependency Walker (3) trying link without Library Dependencies (4) verifying that you have not specified something (strange) in Additional Dependencies (linker Input).

Does the dll work if called from Fortran exe?

A.
I did not check if the DLL would run in Fortran, and it does NOT! However, I am simply extracting elements from a working program to put into a DLL. The subroutines are literally copied out of a working directory into a new project and compiled into the DLL. Why would the program work but an exported DLL fail? Sorry if these are dumb questions, but while I am an experienced Fortran programer, I know nothing about dealign with DLLs...
mountain_ike1
初學者
2,798 檢視
Quoting - mountain_ike
I did not check if the DLL would run in Fortran, and it does NOT! However, I am simply extracting elements from a working program to put into a DLL. The subroutines are literally copied out of a working directory into a new project and compiled into the DLL. Why would the program work but an exported DLL fail? Sorry if these are dumb questions, but while I am an experienced Fortran programer, I know nothing about dealign with DLLs...
Let me expand on this a little. My DLL consists of the following test subroutine:

subroutine AMPdUP(testin,testout)
!DEC$ ATTRIBUTES DLLEXPORT::AMPdUP
!DEC$ ATTRIBUTES ALIAS:'AMPdUP'::AMPdUP
implicit none
real testin,testout

testout=2.0
end subroutine

If this is the only file in the DLL project, everything works. If I add the files containing a bunch of other subroutines (from the working program) to the project - without any additional exports or changes to this subroutine - the DLL crashes. I'm baffled!
ArturGuzik
傑出貢獻者 I
2,798 檢視
Quoting - mountain_ike
Why would the program work but an exported DLL fail?

frustrating, isn't it? Well, on the positive note, I'd say your dll problem is not related to calling it from C#, so we're substantially narrowing down the possibilities. With calls to dll many things can go wrong. Trying to track the problem, (using pure Fortran):

(1) check the dependencies (Dependency Walker) and export symbols (dumpbin) for "working" dll call
(2) check the same after adding new routines (any changes (dependencies))?
(3) make sure you're statically linking (your dll project), this will help avoiding a few problems

How do you "dll import" your routine(s) in main (use explicit interfaces)? Add *.lib as a reference to your project, maybe compiler/linker will detect something.

Are the other routines depending on something else (MKL?, other libraries?) I assume that you're adding the routines as a source code.

A.


EDIT

what's the crash info displayed (message) once called from Fortran exe?
mountain_ike1
初學者
2,798 檢視
Quoting - ArturGuzik

frustrating, isn't it? Well, on the positive note, I'd say your dll problem is not related to calling it from C#, so we're substantially narrowing down the possibilities. With calls to dll many things can go wrong. Trying to track the problem, (using pure Fortran):

(1) check the dependencies (Dependency Walker) and export symbols (dumpbin) for "working" dll call
(2) check the same after adding new routines (any changes (dependencies))?
(3) make sure you're statically linking (your dll project), this will help avoiding a few problems

How do you "dll import" your routine(s) in main (use explicit interfaces)? Add *.lib as a reference to your project, maybe compiler/linker will detect something.

Are the other routines depending on something else (MKL?, other libraries?) I assume that you're adding the routines as a source code.

A.


EDIT

what's the crash info displayed (message) once called from Fortran exe?
Nothing like drilling into the grim details...
As it turns out, when I build the simple DLL it has MSVCR80D.dll and KERNAL32.dll for dependencies. When I build the full complex DLL is has 2 more dependencies: libifcoremdd.dll and libmmdd.dll. The crash states that the libifcoremdd.dll is "either not designed to run on Windows or it contains an error." It suggests that there is an error with the libifcoremdd.dll and that I should contact the vendor...
mountain_ike1
初學者
2,798 檢視
I found an answer on a Cornell University web site...apparently I need to add the offending Fortran DLLs directly to the directory with the executable. From what I've read, it appears to be a problem with the debugging version of the DLLs. I wonder if it exist for later versions of the compiler?
Steven_L_Intel1
2,798 檢視
Are you copying debug DLLs to another system that does not have IVF and VS installed? Don't do that - such DLLs are not redistributable. Build your DLLs as Release confgurations instead. Your license does not allow copying of the debug run-time DLLs.
ArturGuzik
傑出貢獻者 I
2,798 檢視
Quoting - mountain_ike
I found an answer on a Cornell University web site...apparently I need to add the offending Fortran DLLs directly to the directory with the executable.

So we started with 'System.BadImageFormatException' in C# and ended up that actually you're using the dll on different machine and try to redistribute debug dll(s)? is this the case?

A.
mountain_ike1
初學者
2,798 檢視
Are you copying debug DLLs to another system that does not have IVF and VS installed? Don't do that - such DLLs are not redistributable. Build your DLLs as Release confgurations instead. Your license does not allow copying of the debug run-time DLLs.
Iam not (nor have I planned to) redistribute the debug version of my DLL. All I want to do it get it to run on my machine. By making no changes to the VS2005 project I can get it to run if I copy the libifcoremd.dll and the libmmd.dll to the directory where I am building my executable. I want to be clear that, if I change nothing but remove these DLLs from the executable's directory the program crashes. I checked to see if this was still true for the release version, and it is. I must include those two DLLs together with the executable (and my DLL) if I want this to run. While this is a workaround for development purposes, this is obviously not a viable solution. Could it be I simply need to update my Fortran compiler? (and please know that I greatly apprecieate all of this help!)
Steven_L_Intel1
2,798 檢視
Ok. When the compiler installs, it asks you if it is ok to update the PATH system environment variable so that DLL-linked applications can run. It would appear that you did not allow this to happen.

Edit your system PATH environment variable to add:

%IFORT_COMPILER11%libia32
mountain_ike1
初學者
2,798 檢視
Ok. When the compiler installs, it asks you if it is ok to update the PATH system environment variable so that DLL-linked applications can run. It would appear that you did not allow this to happen.

Edit your system PATH environment variable to add:

%IFORT_COMPILER11%libia32
I have the correct path in then environment variables, and the error message I get correctly identifies the location of the offending DLL (see reply #7). And I have this same problem when I use the release version as well. However I might be going back to the 64 but problem. When it crashes it crashes on the file libifcoremd.dll in the EM64T sub-directory. Why would it go there rather than to the ia32 directory? I'm sorry if these are dumb questions, but I am brand new to any kind of DLL programing...
ArturGuzik
傑出貢獻者 I
2,798 檢視
Quoting - mountain_ike
However I might be going back to the 64 but problem. When it crashes it crashes on the file libifcoremd.dll in the EM64T sub-directory. Why would it go there rather than to the ia32 directory?

Hi,

now we're close to (finally) make it. Are you using version 11.x? This Compiler 9.1.3192.2005 is the VS integration number, isn't it? If not you need to adjust path entry Steve gave you last time. It looks as if you've installed 32 and 64 development components. In VS are you using correct (32-bit) project configuration?

A.
mountain_ike1
初學者
2,798 檢視
Quoting - ArturGuzik

Hi,

now we're close to (finally) make it. Are you using version 11.x? This Compiler 9.1.3192.2005 is the VS integration number, isn't it? If not you need to adjust path entry Steve gave you last time. It looks as if you've installed 32 and 64 development components. In VS are you using correct (32-bit) project configuration?

A.
I believe that I have found the problem, and it was nothing like where we thought it would be. I am currently using Fortran 9.1. I had the full path descriptions already listed in the environment variables from when I installed the compiler. However, the way the path statement was originally set up it listed the 64-bit path first, then the 32-bit path in the following way:%IFORT_COMPILER91%EM64TBin;%IFORT_COMPILER91%IA32Bin. Simply changing the order in which the path statements were listed corrected the problem! A simple solution to what looked like a thorny problem. A question that I am left with is, shouldn't the compiler know which of the two directories to go to for a 32-bit compilation? I can only assume now that, if I tried to build a 64-bit program (which I can't because I don't have a 64-bit computer) that I would have to change the path assignment back.
Steven_L_Intel1
2,798 檢視
Yes, this is a problem. When on a x64 system, the compiler install does not know if you are running 32-bit or 64-bit executables. I believe that for version 11, it puts only the "native" lib folder in PATH. Unfortunately, this means that you have to do something special to run 32-bit apps linked to the DLL libraries. It isn't a compiler issue in that the compiler is not in the picture when the choice is made.

We had looked at using shared assemblies, the way Microsoft does, but MS warned us away from that as leading to further problems. They did not offer a better alternative though.
mountain_ike1
初學者
2,798 檢視
Yes, this is a problem. When on a x64 system, the compiler install does not know if you are running 32-bit or 64-bit executables. I believe that for version 11, it puts only the "native" lib folder in PATH. Unfortunately, this means that you have to do something special to run 32-bit apps linked to the DLL libraries. It isn't a compiler issue in that the compiler is not in the picture when the choice is made.

We had looked at using shared assemblies, the way Microsoft does, but MS warned us away from that as leading to further problems. They did not offer a better alternative though.
Steve, thanks for the reply. I will eliminate the 64-bit path and I think that will clear up all future problems...strange how this problem finally got resolved!
回覆