开发者

Unmanaged dll function byte* parameter return in C#

开发者 https://www.devze.com 2023-01-22 16:34 出处:网络
I need to use an unmanaged VC++ dll. It has the following two functions that require C# wrappers: bool ReadData(byte* byteData, byte dataSize);

I need to use an unmanaged VC++ dll.

It has the following two functions that require C# wrappers:

bool ReadData(byte* byteData, byte dataSize);
bool WriteData(byte* byteData, byte dataSize);

They both return true if they succeed, but false otherwise.

Currently in C# I have a class (WRAP) with functions:

[DllImport("kirf.dll", EntryPoint = "ReadData", SetLastError=true)]
[return: MarshalAs(UnmanagedType.VariantBool)]
public static extern Boolean ReadData([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]out Byte[] bytesData, Byte dataSize);

[DllImport("kirf.dll", EntryPoint = "WriteRFCard", SetLastError = true)]
[return: MarshalAs(UnmanagedType.VariantBool)]
public static extern Boolean WriteRFCard[In]Byte[] bytesData, [In]Byte dataSize);

I then have

byte[] newData = new byte[17];
byte dataSize = 17;
bool result = WRAP.ReadData(out newData, dataSize);

This always gives me a result=false, newData = null, and no error thrown(or rather it always come back successful).

And

byte[] bytesData = new Byte[] { (byte)0x9B, (byte)0x80, (byte)0x12, (byte)0x38, (byte)0x5E, (byte)0x0A, (byte)0x74, (byte)0x6E, (byte)0xE6, (byte)0xC0, (byte)0x68, (byte)0xCB, (byte)0xD3, (byte)0xE6, (byte)0xAB, (byte)0x9C, (byte)0x00 };
byte dataSize = 17; 
bool actual = WRAP.WriteData(bytesData, dataSize);

Any ideas as to what I could be doing wrong?

edit

T开发者_Go百科his is how I eventually managed it:

        [DllImport("kirf.dll", EntryPoint = "ReadData", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.VariantBool)]
        public static extern Boolean ReadData([Out] Byte[] bytesData, Byte dataSize);

[DllImport("kirf.dll", EntryPoint = "WriteData", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.VariantBool)]
        public static extern Boolean WriteData([In] Byte[] bytesData, Byte dataSize);

And:

Byte[] newData=new byte[17];
bool result = KABA_KIRF.ReadData(newData, (Byte)newData.Length);

and

bool result = KABA_KIRF.WriteData(data, datasize);

where data was a Byte[] parameter passed into the function.


Does ReadData create a new byte array? Otherwise, I don't think bytesData should be an out param.

Look at the PInvoke spec of ReadFile for comparison:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer,
   uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);

lpNumberOfBytesRead is an out param, because ReadFile changes the value of it. i.e. if you pass a local variable for lpNumberOfBytesRead, ReadFile will change the value on the stack. The value of lpBuffer on the other hand is not changed: It still points to the same byte array after the call. The [In,Out]-Attributes tell PInvoke what to do with the contents of the array you pass.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号