DLLImport c ++函数具有char *输入和输出参数

时间:2014-11-19 08:17:35

标签: c# pinvoke dllimport

使用DllImport有很多关于某些特定问题的文章。 唉,我常常看到对同一个问题的不同回复。 例如有人说如果一个c ++函数返回一个char *和一个int * strLen,那么有人说我应该在我的dllImport语句中使用StringBuilder而其他人说返回byte [],有些人在dllImport中有一个marshall语句,有些人不赞成“T。由于旧的C#/ .net版本,似乎需要一些答案。

所以问题是:如果来自c ++的dll调用相当简单,没有奇怪的调用约定或其他奇怪的项目,如果你有输出char *和size或者输入char *和size,相应的DllImport函数应该是什么?

c++ .h
bool SendString(const char* pSendStr, long strSize);
bool ReadString(char* pReadStr, long& readStrSize); 

相应的DllImports是什么?用字符串替换instr和outstr? StringBuilder的?的char []?字节[]?是否需要任何元帅声明?

2 个答案:

答案 0 :(得分:5)

bool SendString(const char* pSendStr, long strSize);

这个功能很简单。文本从调用者发送到被调用者。 p / invoke声明如下:

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern bool SendString(string SendStr, int Len);

请注意,我假设cdecl调用约定,因为这是C ++代码的默认值。并且还要注意Windows上的C ++中的long是32位宽。所以它匹配C#中的int

调用函数时,需要传递字符串及其长度。但是,常规约定是使用以null结尾的字符串,因此不需要length参数。我会声明这样的非托管函数:

bool SendString(const char* pSendStr);

这样的p / invoke:

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern bool SendString(string SendStr);

另一个功能稍微复杂一些。你已经宣布它是这样的:

bool ReadString(char* pReadStr, long& readStrSize); 

这里调用者分配由被调用者填充的缓冲区。您可以使用StringBuilder作为文本,让编组人员为您完成工作。 p / invoke是:

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern bool ReadString(StringBuilder ReadStr, ref int Len);

约定是您提供提供的缓冲区的长度。反过来,该函数将让您知道它写了多少个字符。你可以这样调用这个函数:

int len = 256;
StringBuilder ReadStr = new StringBuilder(len);
bool succeeded = ReadString(ReadStr, ref len);
if (succeeded)
{
    string str = ReadStr.ToString();
}

答案 1 :(得分:2)

正如leppie所写,你通常想要的是:

[DllImport(my.dll)]
static extern bool SendString(string sendString, int stringSize);
[DllImport(my.dll)]
static extern bool ReadString(StringBuilder readString, ref int readStringSize);

这将为您自动转换为Unicode(和返回)。

如果要精确访问char *,可以使用byte []。这样就不会进行转换,您可以更好地控制正在进行的操作。通常你不会需要它。一个用例可能是当你的char *包含\ 0 chars。