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

Har*_*lse 0 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); 
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*nan 5

bool SendString(const char* pSendStr, long strSize);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

bool SendString(const char* pSendStr);
Run Code Online (Sandbox Code Playgroud)

并且p/invoke像这样:

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern bool SendString(string SendStr);
Run Code Online (Sandbox Code Playgroud)

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

bool ReadString(char* pReadStr, long& readStrSize); 
Run Code Online (Sandbox Code Playgroud)

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

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

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

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