Stack overflow exception calling Fortran dll function from C#
I have an existing VB6 program that calls a Fortran dll with the following definition:
Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Integer
We are in the process of migrating the VB6 application to C# (.net 4.0) and the definition is now as follows:
[DllImport("BackEndLib2.dll", EntryPoint = "_START@0")]
public static extern short START();
However, when I call the same function call in c#, it executes the dll call successfully returns to managed code and than throws a stack overflow exception after a while.
I also tried the same dll call in VB.net with the same result:
Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Short
Any idea why the same function call yields a stack overflow exception in .NET 4.0 but works successfully in vb6?
I'm guessing I'm corrupting the stack with the dll call but I'm not sure. I tried many different parameter types but nothing has worked so far.
Edit: This onl开发者_如何学运维y seems to be an issue in WPF and if I create the same sample in Windows Forms it does not crash.
Your [DllImport] declaration is equivalent to the VB6 declare statement. It is probably best to assume that the VB6 declaration was wrong to begin with an that you got away with it by luck. The return type is quite odd, but that can't cause a stack problem since the return value is passed through a CPU register, not the stack.
Start diagnosing this with Debug + Windows + Registers. Pay attention to the value of ESP before and after the call. If it is not the same then you really do have a declaration problem and lots of calls to this function can blow the stack. Not that likely btw, this normally generates an MDA warning. If it matches then it can only be the Fortran code that overflows the stack.
Also keep in mind that you might be blaming the wrong function. The function that generates the SOE might not be the one that screwed the stack up. Looking at the ESP value lets you quickly find the trouble-maker.
My experience would say if you have a FORTRAN declaration like:
INTEGER*4 FUNCTION START( )
CDEC$ATTRIBUTES STDCALL, DLLEXPORT :: START
C..... BODY HERE
ENDFUNCTION
Perhaps you should try the following:
[DllImport(..., CallingConvention = CallingConvention.StdCall)]
public static extern int Start( );
Out of curiosity, which FORTRAN compiler generated that DLL? Did you specify that it should be exported as STDCALL? You may have to change the calling convention to C as well.
精彩评论