使用C#中的char * param调用DLL函数?

时间:2009-05-20 16:48:05

标签: c#

我有一个需要从C#调用的C ++ DLL。 dll中的一个函数需要char *作为输入参数,另一个函数使用char *作为输出参数。

从C#调用这些内容的正确方法是什么?

5 个答案:

答案 0 :(得分:3)

如果参数是只读的,则

字符串应该有效,如果方法修改了字符串,则应使用StringBuilder。

以下参考示例:

 [DllImport ("libc.so")]
 private static extern void strncpy (StringBuilder dest, 
      string src, uint n);

 private static void UseStrncpy ()
 {
    StringBuilder sb = new StringBuilder (256);
    strncpy (sb, "this is the source string", sb.Capacity);
    Console.WriteLine (sb.ToString());
 }

如果你不知道p / invoke marshaling是如何工作的,你可以阅读http://www.mono-project.com/Interop_with_Native_Libraries

如果您只是在使用字符串,请阅读以下部分:http://www.mono-project.com/Interop_with_Native_Libraries#Strings

答案 1 :(得分:2)

使用字符串对输入参数可以正常工作,但您可以使用MarshalAs属性控制有关字符串的详细信息。 E.g。

[DllImport("somedll.dll", CharSet = CharSet.Unicode)]
static extern void Func([MarshalAs(UnmanagedType.LPWStr)] string wideString);

至于返回char *参数,由于涉及对象所有权,这有点复杂。如果您可以更改C ++ DLL,则可以使用CoTaskMemAllocate,例如:

void OutputString(char*& output)
{
    char* toCopy = "hello...";
    size_t bufferSize = strlen(toCopy);
    LPVOID mem = CoTaskMemAlloc(bufferSize);
    memcpy(mem, toCopy, bufferSize);
    output = static_cast<char*>(mem);
}

然后C#端只使用'out string'参数,垃圾收集器可以获取字符串的所有权。

另一种方法是使用StringBuilder,但是在实际调用函数之前你需要知道字符串的大小。

答案 2 :(得分:0)

如果DLL函数期望分配char*的缓冲区(而不是宽/多字节缓冲区),则可以执行以下操作:

[DllImport("somedll.dll", CharSet = CharSet.Ansi)]
static extern void TheFunc(byte[] someBuffer, int someSize);

这里,将在c#中分配的缓冲区传递到TheFunc,该缓冲区用一个字符字符串(char类型)填充。字节不是由C#“解释”的,它们被视为8位整数,因此非常适合保存8位字符。

因此,一个示例代码将被删除:

byte[] mybuffer;
int bufSize;

bufSize = 2048;
mybuffer = new byte[bufSize];

TheFunc(mybuffer, bufSize);

string value;
for(value = "", int ix  = 0; (mybuffer[ix] != 0) && (ix < bufSize); ix++)
  value += (char) mybuffer[ix];

DoSomethingWithTheReturnedString(value);

答案 3 :(得分:0)

不确定这是否有效,但您是否尝试过使用

StringObject.ToCharArray();

不确定从char * tho初始化String。 Mybe只是分配给一个字符串对象,值得一试。

答案 4 :(得分:0)

你试过StringBuilder吗?我在Google搜索中找到了这个:

[DllImport("advapi32.dll")]
public static extern bool GetUserName(StringBuilder lpBuffer, ref int nSize);

如果你发布了正在发出的电话,我们可以帮你组装。