在C#和DLL之间(双向)传递数组数据 [英] Passing array data between C# and a DLL (both directions)

查看:82
本文介绍了在C#和DLL之间(双向)传递数组数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些可以编译为DLL的C代码.从C#中,我需要向其传递一个整数数组,并且需要从中获取一个整数数组.

I have some C code that compiles to a DLL. From C#, I need to pass an array of ints to it, and I need to get an array of ints out of it.

这是我到目前为止所拥有的.在C#中,唯一起作用的函数是bar().它返回22并按预期写入文件.其他人正确地写入他们的文件,但是在将控制权交还给C#时抛出异常.它的内容是

Here's what I have so far. From C#, the only function that works is bar(). It returns 22 and writes to a file as expected. The others write to their files properly but throw an exception when control is given back to C#. It reads,

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

"A call to PInvoke function 'irhax!irhax.App::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."

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)正常工作,因此这似乎是一个不错的起点.

I'm at a loss here. What am I doing wrong? Since I can't even get foo(int) to work, that seems like a good place to start.

推荐答案

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

Your C code uses cdecl calling convention. The C# code uses stdcall.

所有 DLLImport 属性应为:

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

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

Of course you could alternatively switch the C code to stdcall using __stdcall. But make sure you only do one of these!

receiveIR 不需要 out .您应该声明它:

receiveIR doesn't need the out. You should declare it:

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

这篇关于在C#和DLL之间(双向)传递数组数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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