【发布时间】:2011-02-22 05:06:06
【问题描述】:
我目前正在研究一个与互操作相关的问题,并编写了一个小型测试程序来帮助我弄清楚发生了什么(有问题的问题涉及对更复杂的本机函数的调用,并且很难发布在这里)。
无论如何,我有一个非常简单的原生 dll,其中仅包含以下代码:
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# 调用这个函数的:
[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 );
}
在执行“测试”时,我收到以下错误:
检测到 PInvokeStackImblanace
对 PInvoke 函数“WindowsFormsApplication2!WindowsFormsApplication2.Form1::Foo”的调用使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。
所以,我不是互操作专家,但我看不出这段代码有什么问题。本机签名需要一个指向 int 的指针,我正在传递对 int[] 的引用。也就是说,它不起作用,所以我一定是错了。提前致谢。
编辑:好的,我将测试改为尽可能简单:
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 );
}
导致相同的错误。我是否错过了一些关于互操作中使用的调用约定的完整课程?这是怎么回事?
【问题讨论】: