从 C# 调用 C dll,return 类型略有不同

Calling C dll from C#, return types slightly different

我用 C 编写了一个 dll,它具有在 C# 中引用 DLL 时可以调用的函数。如果我使用像 int 这样的基本类型,它工作正常,但由于语言差异,我的结构在 C# 中与在 C 中略有不同。这是一个例子。这是C#中的函数定义:

[DllImport("hello_world_cuda.dll", CharSet = CharSet.Auto)]
public static extern Batch Cut();

C:

extern "C" Batch __declspec(dllexport) __stdcall Cut()

可以看到return类型的Batch是一样的,不过这里是它在C#中的定义

class Envelope
{
    public byte[] Payload;
    public byte[] Signature;
}

class Batch
{
    public Envelope[] Messages;
    public int MsgCount;
}

这里是C

中的定义
struct Envelope
{
public:
    char* Payload;
    char* Signature;
};

struct Batch
{
public:
    Envelope* Messages;
    int MsgCount;
};

如何克服这些语言差异才能在 C# 中成功调用 DLL?

您也应该在 C# 中将 EnvelopeBatch 定义为结构,并应用 StructLaylout 属性:

例如:

[StructLayout(LayoutKind.Sequential, Pack=0)]
struct Envelope
{
   ...
}

非托管语言中的指针不会像您所做的那样映射到托管数组,这就是它抱怨的原因。 char 是(几乎总是,除了非常有限的例外)一个 8 位值,正如您所注意到的那样,它可以很好地映射到 C# 中的 byte,但是您还需要使它们成为托管结构中的指针:

unsafe struct Envelope
{
    public byte* Payload;
    public byte* Signature;
}