我在用c ++创建的dll中有这个
extern "C" __declspec(dllexport)
char* __stdcall hh()
{
char a[2];
a[0]='a';
a[1]='b';
return(a);
}
这就是我试图处理c#
中的代码的方法[DllImport(@"mydll.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr hh();
static void Main(string[] args)
{
IntPtr a = hh();
//How to proceed here???
}
}
帮助继续进行。
答案 0 :(得分:3)
无法处理此类数组。 {C}函数在堆栈中分配char a[2]
,并在返回时立即销毁。您应该从C#传递一个数组并将其填入C ++代码中,或者在堆中分配数组并提供一些释放它的方法。
如果更正,处理将取决于您如何从C ++代码返回数据。如果它仍然是IntPtr,你可以使用Marshal.ReadByte方法从内存中读取字符,并在必要时使用Encoding方法将这些字节转换为字符串。
const int bufferSize = 2; // suppose it's some well-known value.
IntPtr p = ...; // get this pointer somehow.
for (var i = 0; i != bufferSize; ++i)
{
var b = Marshal.ReadByte(p, i);
Console.WriteLine(b);
}
答案 1 :(得分:2)
我得到了如下解决方案::
我们的C ++代码如下
extern "C" __declspec(dllexport)
char** __stdcall hh()
{
static char* myArray[3] = {"A1", "BB2", "CC3",};
return myArray;
}
C#如下:
[DllImport(@"ourdll.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr hh();
static void Main(string[] args)
{
IntPtr a = hh();
int j = 0;
string[] s=new string[100];
do
{
s[j] = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(a,4*j));
j++;
}
while(s[j-1] != null);
}
现在面临的唯一问题是我们怎么知道数组的大小 所以在这个声明中 string [] s =新字符串[100]; 我们不需要浪费我们的记忆。
答案 2 :(得分:1)
答案是
string stra = Marshal.PtrToStringAnsi(a);
但是你也有问题,dll会根据你的代码返回垃圾,因为char *是一个本地的c样式字符串。 如果你会返回类似的东西,那就没关系了。
const char* str = "Hello from DLL.";
答案 3 :(得分:-2)
尝试使用非空StringBuilder作为返回值。