Simple Interop Test; Stack Unbalanced by a simple call

a 夏天 提交于 2019-12-20 04:23:46

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!