在C#中将byte[]转换为byte*

7

我创建了两个程序 - 一个是用C#写的,一个是用C++写的,它们都调用了本地的C dll方法。C++可以正常工作,因为数据类型相同,但C#无法正常工作。

原生函数参数是unsigned char*。我在C#中尝试使用byte[],但不起作用,然后我尝试了:

fixed(byte* ptr = byte_array) {
  native_function(ptr, (uint)byte_array.Length);
}

它还是不起作用。将字节数组转换为byte*的方式正确吗?在C#中使用byte作为C中的unsigned char也是正确的吗?
编辑: 这个东西返回了错误的结果:
byte[] byte_array = Encoding.UTF8.GetBytes(source_string);
nativeMethod(byte_array, (uint)byte_array.Length);

这段代码也会返回错误的结果:

 byte* ptr;
 ptr = (byte*)Marshal.AllocHGlobal((int)byte_array.Length);
 Marshal.Copy(byte_array, 0, (IntPtr)ptr, byte_array.Length);

1
请具体说明 - 什么不起作用?它无法编译,编译后崩溃,结果错误等? - larsmoa
没有任何异常抛出,所有内容都已编译完成,但是函数返回了错误的结果。 - Sergey
1
如果你无法让byte[]工作,那么byte*也不会起作用。你需要发布更多的代码来帮助我们帮助你。 - Hans Passant
它使用确定的值填充数组。如果数组的大小小于所需大小(10),则返回false。如果我创建一个只有3个元素的数组,它仍然返回true。 - Sergey
我将其作为第二个参数传递,虽然在这种情况下没有意义,但会添加。 - Sergey
3个回答

6
unsafe class Test
{
    public byte* PointerData(byte* data, int length)
    {
        byte[] safe = new byte[length];
        for (int i = 0; i < length; i++)
            safe[i] = data[i];

        fixed (byte* converted = safe)
        {
            // This will update the safe and converted arrays.
            for (int i = 0; i < length; i++)
                converted[i]++;

            return converted;
        }
    }
}

您还需要在构建属性中设置“使用不安全代码”复选框。


2
您需要对byte[]进行编组:
[DllImport("YourNativeDLL.dll")]
public static extern void native_function
(
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
    byte[] data,
    int count // Recommended
);

1
LPArray是默认的封送类型,这对OP没有帮助。 - Hans Passant

0
你可以分配一个非托管数组,并使用 Marshal.Copy 将托管的 byte[] 数组的内容复制到非托管的 unsigned char* 数组中。请注意,非托管资源必须手动清理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接