我有一个用C编码的DLL,它具有将图像数据输出为unsigned char *的函数,在不同的图像格式之间进行转换等等。我有一个客户想要从C#中使用它。我猜C#端的适当数据类型是byte []。
我认为PInvoke会有所帮助,但是我无法找到合适的技术来编制这个"二进制数据"到C#(其变量长度存储在一个单独的变量中)。我见过的所有编组示例都涉及空终止字符串,并且图像数组不会停止在ascii null。
我已经看到我可能会考虑通过IntPtr将指针传递给数据但是它 看起来这会涉及到C#端的不安全代码。
答案 0 :(得分:1)
您想要分配全局内存GlobalAlloc
然后在C#中,您需要将指针编组为托管类型。
对于字符串,我使用以下代码,(您可以根据需要调整它):
public static string GetString() {
IntPtr str = mylib.getstring(); //get native pointer
if (str == IntPtr.Zero)
return null;
string newStr = Marshal.PtrToStringAnsi(str); //marshall to managed string
Marshal.FreeHGlobal(str); //free memory
return newStr;
}
编辑:忘了提及如何PInvoke你的库:
class mylib {
[DllImport("mylib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr getstring();
}
另外不要忘记导入System.Runtime.InteropServices
答案 1 :(得分:0)
好的,George TG的回答让我走上了正确的道路,(谢谢!)但是假设我们有一个带签名的功能 void fillBytes(unsigned char * outBytes,int nbBytes); 在C端,在outBytes中将nbBytes写入数组,然后C#端可以写成:
class Program
{
[DllImport("FixedSizeString", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void fillBytes(IntPtr buffer, int nbBytes);
void main(string[] args)
{
int BUFFSIZ = 256;// corresponds to the number of bytes in the buffer
IntPtr iptr = Marshal.AllocHGlobal(BUFFSIZ);
byte[] buffer = new byte[BUFFSIZ];
if (iptr == IntPtr.Zero)
Console.WriteLine("Allocation failed");
else
{
fillBytes(iptr, BUFFSIZ);
for (int i = 0; i < BUFFSIZ; ++i)
{
buffer[i] = Marshal.ReadByte(buffer, i);
}
Marshal.FreeHGlobal(iptr);
// now deal with buffer here ...
}
}
}