【发布时间】:2021-10-18 23:13:45
【问题描述】:
在以下示例中,我尝试通过将值传递给 C++ dll 并返回单个字符串来连接两个无符号字符(这是必需的)。我得到的输出不正确。
C#:
using System;
using System.Runtime.InteropServices;
using System.Text;
class HelloWorld
{
[DllImport("cpp_func.dll")]
public static extern IntPtr concat_fun(byte[] a,byte[] b, int c, int d);
static void Main()
{
int x,y;
IntPtr return_value;
string hello = "hello", world = "world", final;
byte[] hel = Encoding.ASCII.GetBytes(hello);
byte[] wor = Encoding.ASCII.GetBytes(world);
x = hel.Length;
y = wor.Length;
return_value = concat_fun(hel, wor, hel.Length, wor.Length);
final = Marshal.PtrToStringAuto(return_value);
Console.WriteLine("Concatenated string:" +final);
Console.Read();
}
}
我已将它们声明为 byte[],因为这就是 .NET 中原生类型 uint8_t 的表示方式(https://docs.microsoft.com/en-us/dotnet/standard/native-interop/type-marshaling) 我已经将两个字节数组及其长度作为参数传递了。
C++:
_declspec(dllexport) unsigned char * concat_fun(unsigned char a[], unsigned char b[], int d, int e) {
int i, ind = 0;
unsigned char c[20];
for (i = 0; i < d; i++) {
c[ind] = a[i];
ind++;
}
for (i = 0; i < e; i++) {
c[ind] = b[i];
ind++;
}
return c;
}
我得到的输出是这样的:
Concatenated string:????????????????
如何获得连接的字符串? 注意:将输入作为 dll 函数参数的无符号字符,是一项要求 我知道我在这里犯了一些小错误,因为我只是一个初学者。
【问题讨论】:
-
这个问题与 C# 无关,与没有意识到
c是一个超出范围的局部变量有关。您的编译器是否警告过您?如果是这样,这就是您不忽略警告的原因。现在如何从导出的 DLL 函数中正确返回字符串是另一个问题,对此有几个答案。 -
C# 代码应该提供了输出
byte[]缓冲区以将连接的字符串写入 DLL 函数。但是,您当前的函数签名对此没有参数。换句话说,DLL 函数不应该是负责创建缓冲区的函数。如果你这样做了,那么返回一个局部变量就成了一个有争议的问题。 -
这里有数百个关于这个主题的问题。您真正的问题是没有进行足够稳健的研究。您的代码中还有很多其他问题。局部变量返回。对二进制数据而非文本的 unsigned char 的滥用。对可能的缓冲区溢出缺乏关注。文本编码不匹配。坦率地说,您需要先复习一些基础知识,然后才能正确编写此互操作代码,我的意思是希望以一种建设性的方式进行。