将StringBuilder传递给DLL函数时需要char指针
Passing StringBuilder to DLL function expecting char pointer
我正在尝试与Delphi中创建的DLL库进行交互。在C++中,我把这个调用做得非常好:
for(int y = 1; y <= 12; y++)
{
char * chanName = (char *) malloc(21);
memset(chanName,0,21);
channelName(y,20,chanName);
...
}
其中channelName
是定义为typedef int (CALLBACK* ChannelName)(int,int,char*);
的类型
现在我正试图在C#中做同样的事情。我搜索发现StringBuilder
通常用作DLL函数的字符指针。以下是我如何声明我的函数:
[DllImport("myDLL.dll")]
public static extern int ChannelName(int x, int y, StringBuilder z);
以下是我如何称呼它:
for (int x = 0; x < 12; x++)
{
StringBuilder b = new StringBuilder(100);
DLLInterface.ChannelName(x+1, b.Length, b);
Console.WriteLine(b.ToString());
}
这只是让控制台打印出来的jibberish,例如:
☺ §
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
☺ î☺8f9
我记得在C++中遇到过一个类似的问题,这就是为什么我memset
是我malloc
到0的内存。我试图在C#中找到一个等价的,但可能是StringBuilder
的问题?如果我的问题不是很清楚,我只想能够将一个字符串传递到我的函数中,让函数填充它,然后打印出来。字符串在C#中是不可变的,并且不存在好的指针选项,这就是我尝试StringBuilder
的原因。
在.NET中,字符串(和StringBuilders)是16位Unicode字符。我的猜测是,您的本机函数处理8位ASCII字符。您需要告诉Marshaller在编组字符时如何转换字符。更改您的DllImport属性,如下所示:
[DllImport("myDLL.dll", CharSet=CharSet.Ansi)]
public static extern int ChannelName(int x, int y, [Out] StringBuilder z);
更新
此外,您应该在StringBuilder上指定[Out]属性,以便Marshaller只在外出时封送处理,因为您在外出时不传递任何信息。
再次更新
[In,Out]属性是多余的(这是默认值),但将其放在那里会明确表示您希望同时复制In和Out。
[DllImport("myDLL.dll")]
private static extern int ChannelName(int x, int y, [In,Out] byte[] z);
public static int ChannelName(int x, int y, out string result)
{
byte[] z = new byte[100];
int ret = ChannelName(x, y, z);
result = Encoding.ASCII.GetString(z);
return ret;
}
再次更新
看起来(名称不正确)"y"参数是传入的char*缓冲区的长度,我猜它会返回写入缓冲区的字符数。如果是这样的话,我会用一种更自然的C#方式包装这个调用:
[DllImport("myDLL.dll")]
private static extern int ChannelName(int x, int y, [In, Out] byte[] z);
public static string ChannelName(int x)
{
byte[] z = new byte[100];
int length = ChannelName(x, z.Length, z);
return Encoding.ASCII.GetString(z, 0, length);
}
- 构造函数 (C++) 中的 char 指针参数存在问题
- 将 char 指针传递给接受对 char 数组的引用的函数
- 分配值时,C++ char* 指针上的前递增与后递增
- char指针或char变量的默认值是多少
- 为什么为char指针分配内存不会截断char序列
- 愚蠢的问题:strcat和char指针
- 使用 ctypes 从函数返回字符串C++会给出大的 int,而不是 char 指针
- 打印char指针的Unicode和文本值
- 应对 std::字符串中的 std::<char>指针转换后的向量
- 一系列char指针
- 为什么可以将Char指针变量初始化为字符串,而INT指针变量不能初始化到整数数组
- 将char指针传递给cin和cin.get()
- 在C和C++中,将int值转换为char指针的差异
- std :: cout null char*指针中止该程序
- char指针违反访问权限
- const char指针在结构中声明
- 将字符串转换为 char 指针可以指向的 char 数组/值的最有效方法是什么
- 将Char指针数组传递到C 中的函数
- 获取错误C2440:char []* char*(指针)
- 删除Char指针在destructor中不起作用