【问题标题】:DLLImport c++ functions with char* as input or as output parametersDLLImport c++ 函数,带有 char* 输入和输出参数
【发布时间】:2015-01-16 16:23:44
【问题描述】:

有很多关于使用 DllImport 的特定问题的文章。 唉,我经常看到对同一个问题的不同答复。 例如,有人说如果 c++ 函数返回 aa char* 和 int* strLen,那么有人说我应该在我的 dllImport 语句中使用 StringBuilder,而其他人说返回 byte[],有些人在 dllImport 中有一个 marshall 语句,有些人不不。由于旧的 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?字符串生成器?字符[]?字节[]?是否需要任何元帅声明?

【问题讨论】:

  • const char* == stringchar* == StringBuilder(通常)
  • char ***怎么样

标签: c# pinvoke dllimport


【解决方案1】:

正如 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 字符。

【讨论】:

  • long 在 C# 中是 64 位宽。您还错误地处理了ReadString 中的第二个参数。这是一个参考。
【解决方案2】:
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

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

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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2017-08-02
    • 1970-01-01
    相关资源
    最近更新 更多