We're building an application on c#, .net 4.0, on Win7 x64, targeting x32.
We are using a 3rd party library in our application. We understand that this library is written using C++. However, to let c# developers use this library, they've wrapped it using P/Invoke, so that's how we call the API functions.
One of the API calls is as follows:
ReadFromDevice(int deviceAddress, int numBytes, Byte[] data);
This function reads numBytes of data from an external device and places it in data[]. As you can see, it expects to see a C# Byte array as the 3rd argument. Now, our problem is, we would like to read data to an arbitrary location in a predeclared array. For example:
Byte[] myData = new Byte[1024*1024*16];
ReadFromDevice(0x100, 20000, &myData[350]) // Obviously not possible in C#
If we were using C/C++, this would be trivial. Given that the underlying API is written in C++, I feel that we should be able to do this in c# as well, however, I can't figure out how to do this in c#. Maybe we can somehow call the underlying library not through the supplied P/Invoke interface and write a custom interface?
Any ideas would be appreciated.
Regards,
While the other answers here are close, none are quite complete.
First you simply need to declare your own p/invoke declaration. This is the sweet thing about p/invoke; There's never just one way to do it.
[DllImport("whatever.dll")]
unsafe extern static void ReadFromDevice(int deviceAddress, int numBytes, byte* data);
Now you can call it with
unsafe static void ReadFromDevice(int deviceAddress, byte[] data, int offset, int numBytes)
{
fixed (byte* p = data)
{
ReadFromDevice(deviceAddress, numBytes, p + offset);
}
}
You can use pointers but requires to build with unsafe mode checked.
Byte[] myData = new Byte[1024*1024*16];
fixed( Byte * pB = &myData[350])
{
ReadFromDevice(0x100, 20000,pB )
}
But first you need to change the exported method signature to.
ReadFromDevice(int deviceAddress, int numBytes, Byte * data);
You are still able to perform pointer arithmetic in c#.
If you re-declare you dll import (against the C++ library) to use an IntPtr to pass the byte array , this can be incremented by 350 using the Add method (This actually returns a new intptr)
There is an example of something similar here: http://msdn.microsoft.com/en-us/library/system.intptr.add.aspx#Y811
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With