问题
I am currently looking into an interop related issue and have written a small test program in order to help me figure out what is going on (the issue in question involves a call into a more complicated native function and would be difficult to post here).
Anyways, I have a very simple native dll which includes only the following code:
extern "C" __declspec(dllexport) void Foo( int* arr, int size );
void Foo( int* arr, int size )
{
for( int i = 0; i < size; ++i )
{
*arr++ = i;
}
}
I am calling into this function from C# like so:
[DllImport("Interop.dll")]
public static extern void Foo( int[] arr, int size );
static void Main(...)
{
Test();
}
private static void Test()
{
int[] arr = new int[100];
Foo( arr, arr.Length );
}
Upon executing "Test" I receive the following error:
PInvokeStackImblanace was Detected
A call to PInvoke function 'WindowsFormsApplication2!WindowsFormsApplication2.Form1::Foo' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
So, I am no interop expert, but I don't see the problem with this code. The native signature expects a pointer to int, I am passing in a reference to an int[]
. That said, it doesn't work, so I must be wrong about something. Thanks in advance.
EDIT: Ok, I changed to the test to be as simple as possible:
extern "C" __declspec(dllexport) void Foo( int i );
void Foo( int i ) { }
C#:
[DllImport("Interop.dll")]
public static extern void Foo( int i );
private void Test()
{
Foo( 1 );
}
Results in the same error. Did I miss some integral lesson on calling conventions used in interop? What is going on here?
回答1:
You need to specify a correct calling convention. Default calling convention for C/C++ programs is cdecl, but default calling convention when importing through the PInvoke is StdCall. So you either need to specify the Cdecl
convention when importing or __stdcall
when exporting. For example:
[DllImport("Interop.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo( int i );
private void Test()
{
Foo( 1 );
}
来源:https://stackoverflow.com/questions/5070752/simple-interop-test-stack-unbalanced-by-a-simple-call