[英]How to pass a buffer of binary data from C to C# with pinvoke
I have a DLL coded in C that has functions that output image data as unsigned char *, convert between different image formats and so on. 我有一个用C编码的DLL,它具有将图像数据输出为无符号char *,在不同图像格式之间进行转换等功能。 I have a client who wants to make use of this from C#.
我有一个客户想利用C#的这个功能。 I guess that the apppropriate data type on the C# side would be byte [].
我猜想C#端的适当数据类型将是字节[]。
I thought that PInvoke would help, but I cant find the appropriate technique to marshall this "binary data" to C# (whose variable length is stored in a separate variable). 我以为PInvoke会有所帮助,但是我找不到合适的技术将“二进制数据”编组为C#(其可变长度存储在单独的变量中)。 All the marshalling examples I have seen concern null terminated strings and an image array does not stop at an ascii null.
我见过的所有编组示例都关注以null结尾的字符串,并且图像数组不会在ascii null处停止。
I have seen that I might alternatively consider passing the pointer to the data via an IntPtr but it looks like this would involve unsafe code on the C# side. 我已经看到,我可能会考虑通过IntPtr将指针传递给数据,但看起来这将涉及C#端的不安全代码。
You want to allocate global memory, GlobalAlloc 您想分配全局内存GlobalAlloc
Then in C#, you need to marshall the pointer to a managed type. 然后在C#中,您需要编组指向托管类型的指针。
For a string I am using the following code, (you can adapt it to your needs): 对于字符串,我正在使用以下代码(您可以根据需要对其进行调整):
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;
}
Edit: Forgot to mention how to PInvoke your library: 编辑:忘记提及如何P调用您的库:
class mylib {
[DllImport("mylib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr getstring();
}
Also don't forget to import System.Runtime.InteropServices 同样不要忘记导入System.Runtime.InteropServices
OK, George TG's answer set me on the right path, (thankyou!) but suppose that we have a function with signature void fillBytes(unsigned char *outBytes, int nbBytes); 好的,乔治·TG的答案使我走上了正确的道路(谢谢!),但是假设我们有一个函数,该函数的签名为void fillBytes(未签名的char * outBytes,int为nbBytes); on the C side that writes nbBytes into the array at outBytes then the C#side could be written as this:
在将nbBytes的数组写入outBytes的C端,则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 ...
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.