从 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# 中将 Envelope
和 Batch
定义为结构,并应用 StructLaylout 属性:
例如:
[StructLayout(LayoutKind.Sequential, Pack=0)]
struct Envelope
{
...
}
非托管语言中的指针不会像您所做的那样映射到托管数组,这就是它抱怨的原因。 char
是(几乎总是,除了非常有限的例外)一个 8 位值,正如您所注意到的那样,它可以很好地映射到 C# 中的 byte
,但是您还需要使它们成为托管结构中的指针:
unsafe struct Envelope
{
public byte* Payload;
public byte* Signature;
}
我用 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# 中将 Envelope
和 Batch
定义为结构,并应用 StructLaylout 属性:
例如:
[StructLayout(LayoutKind.Sequential, Pack=0)]
struct Envelope
{
...
}
非托管语言中的指针不会像您所做的那样映射到托管数组,这就是它抱怨的原因。 char
是(几乎总是,除了非常有限的例外)一个 8 位值,正如您所注意到的那样,它可以很好地映射到 C# 中的 byte
,但是您还需要使它们成为托管结构中的指针:
unsafe struct Envelope
{
public byte* Payload;
public byte* Signature;
}