简单的互操作测试;一个简单的调用使堆栈不平衡 [英] Simple Interop Test; Stack Unbalanced by a simple call

查看:74
本文介绍了简单的互操作测试;一个简单的调用使堆栈不平衡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在调查与互操作性相关的问题,并且编写了一个小型测试程序,以帮助我弄清楚发生了什么(有问题的问题涉及调用更复杂的本机函数,并且将很难发布.在这里).

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).

无论如何,我有一个非常简单的本机dll,其中仅包含以下代码:

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;
    }
}

我从C#调用此函数,如下所示:

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

对PInvoke函数'WindowsFormsApplication2!WindowsFormsApplication2.Form1 :: Foo'的调用已使堆栈不平衡.这可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.

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.

因此,我不是互操作专家,但是我看不到这段代码有问题.本机签名需要一个指向int的指针,我正在传递对int[]的引用.就是说,这行不通,所以我在某些方面一定是错的.预先感谢.

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.

好的,我将测试更改为尽可能简单:

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?

推荐答案

您需要指定正确的调用约定. C/C ++程序的默认调用约定为 cdecl ,但是默认调用约定通过PInvoke导入时为 StdCall .因此,在导入时需要指定Cdecl约定,在导出时需要指定__stdcall.例如:

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 );
}

这篇关于简单的互操作测试;一个简单的调用使堆栈不平衡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆