在C#和DLL之间传递数组数据(两个方向)

时间:2011-04-18 21:09:58

标签: c# dllimport

我有一些编译成DLL的C代码。从C#开始,我需要向它传递一个int数组,我需要从中获取一个int数组。

这是我到目前为止所拥有的。从C#开始,唯一有效的功能是bar()。它返回22并按预期写入文件。其他人正确地写入他们的文件,但在将控制权交还给C#时抛出异常。它读,

“调用PInvoke函数'irhax!irhax.App :: foo'使堆栈失衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。请检查PInvoke的调用约定和参数签名匹配目标非托管签名。“

C(DLL):

#define IG_API __declspec(dllexport)

IG_API void foo(int i) {
    FILE *f = fopen("foo.txt", "a+");
    fprintf(f, "%d\n", i);
    fclose(f);
}

IG_API int bar(void) {
    FILE *f = fopen("bar.txt", "a+");
    fprintf(f, "bar!\n");
    fclose(f);
    return 22;
}


IG_API void transmitIR(unsigned *data, int length) {
    FILE *f = fopen("transmit.txt", "a+");
    for(int i = 0; i < length; ++i)
        fprintf(f, "%d, ", data[i]);
    fprintf(f, "\n");
    fclose(f);
}

IG_API int receiveIR(unsigned *data, int length) {
    for(int i = 0; i < length; ++i)
        data[i] = 4;
    return length;
}

C#(来电者):

[DllImport("Plugin.dll")]
static extern void foo(int i);

[DllImport("Plugin.dll")]
static extern int bar();

[DllImport("Plugin.dll")]
static extern void transmitIR(uint[] data, int length);

[DllImport("Plugin.dll")]
static extern int receiveIR(out uint[] data, int length);

我在这里不知所措。我究竟做错了什么?因为我甚至无法让foo(int)工作,所以这似乎是一个好的开始。

2 个答案:

答案 0 :(得分:6)

您的C代码使用cdecl调用约定。 C#代码使用stdcall。

所有DLLImport属性应为:

[DllImport("Plugin.dll", CallingConvention=CallingConvention.Cdecl)]

当然,您也可以使用__stdcall将C代码切换为stdcall。但请确保您只执行其中一项!

receiveIR不需要out。你应该声明它:

static extern int receiveIR(uint[] data, int length);

答案 1 :(得分:1)

你知道C函数的调用约定吗?像错误一样,这可能是不匹配的。默认调用约定是stdcall,但如果这些函数使用cdecl约定,则可能会出现此错误。试试

[DllImport("Plugin.dll", CallingConvention=CallingConvention.Cdecl)]
static extern void foo(int i);