c# - 简单互操作测试;通过简单调用堆栈不平衡

标签 c# interop

我目前正在研究与互操作相关的问题,并编写了一个小测试程序以帮助我弄清楚发生了什么(所讨论的问题涉及对更复杂的 native 函数的调用,因此很难发布在这里)。

无论如何,我有一个非常简单的 native 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 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.

所以,我不是互操作专家,但我看不出这段代码有什么问题。 native 签名需要一个指向 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 );
}

导致相同的错误。我是否错过了一些关于互操作中使用的调用约定的完整类(class)?这是怎么回事?

最佳答案

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

[DllImport("Interop.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo( int i  );

private void Test()
{
    Foo( 1 );
}

关于c# - 简单互操作测试;通过简单调用堆栈不平衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5070752/

相关文章:

C#/C++ 互操作 - 需要帮助定义我的数据结构

c# - P/调用互操作助手 : Is this actually correct?

c++ - 使用 p/invoke 将字符串数组从 C# 编码到 C 代码

c# - godot 上 GetComponent 的类似替代方案

c# - 在 WebAPI 中使用自定义 IHttpActionInvoker 进行异常处理

c# - Url.Action 不适用于非标准 MVC 路由

c# - Blittable 对比IL 中的非 Blittable

c# - Nant 无法构建 c# .net 项目

c# - 折叠后自动调整 TreeView 的大小

执行 Excel 互操作的 C# 控制台应用程序-按计划任务运行时失败-System.UnauthorizedAccessException