Passing dual dimensions array to unmanaged function

G

Guest

In my managed code (C#) I have a some dozens of single dimension byte array.
I get each of this arrays from another unmanaged code (first DLL).
I need to stitch these arrays to a dual dimensions array and to be passed to
a unmanaged DLL (second DLL) that will change the values of this array. When
this unmanaged function returns from the unmanaged DLL, I'll need to use this
changed data.

I have 2 questions:

(1) How can stitch the single dimension byte arrays to a dual dimensions
array and avoiding a data copy to be used in a unmanaged code?
(2) What should the unmanaged function signature be?
e.g. void UnmanagedFuc(BYTE** buff) ???
(3) How do I use/import the unmanaged function using the DllImport?
e.g.
[DllImport(Unmanaged.dll")]
public static extern void UnmanagedFuc(ref byte[,] buff);
 
E

eusebiu

Hi Sharon,
I also have in my application some byte arrays and I send them to an
unmanaged dll but I am using IntPtr like this :
C++ : void UnmanagedFuc(BYTE** buff)
C# : [DllImport(Unmanaged.dll")]
public static extern void UnmanagedFuc(ref IntPtr pointerToBuff);

And to get the pointerToBuff, I am using
pointerToBuff = Marshal.AllocHGlobal(IntPtr.Size);
Marshal.Copy(buff, pointerToBuff, 0, buff.Length);
//call UnmanagedFunction
UnmanagedFuc(ref pointerToBuff);

Hope this helps...
 
E

eusebiu

Don't forget to use Marshal.FreeHGlobal(pointerToBuff); after you get
the information by calling the UnmanagedFuc.
 
G

Guest

Thanks,
Can you tell me:
(1) Does the C++ function void UnmanagedFuc(BYTE** buff) takes a dual
dimensions array BYTE[][] or a single dimensions array?
(2) In which case do you use the BYTE** instead of BYTE*?
(3) In the C++ code, how do you access the buff argument? Can you access it
using [][] or else?
 
E

eusebiu

Hi Sharon...
(1)UnmanagedFuc(BYTE** buff) takes a dual dimensions array BYTE[][];
(2)I use Byte** when I send a pointer to an array.
(3)I guess you can using [][]... Sorry, I am not very sure... maybe a C
++ developer will answer better than me at these questions.
 
B

Ben Voigt [C++ MVP]

eusebiu said:
Hi Sharon,
I also have in my application some byte arrays and I send them to an
unmanaged dll but I am using IntPtr like this :
C++ : void UnmanagedFuc(BYTE** buff)

No reason for double indirection, just use BYTE*
C# : [DllImport(Unmanaged.dll")]
public static extern void UnmanagedFuc(ref IntPtr pointerToBuff);

and then remove "ref" to match, you're not changing the pointer
 
B

Ben Voigt [C++ MVP]

eusebiu said:
Hi Sharon...
(1)UnmanagedFuc(BYTE** buff) takes a dual dimensions array BYTE[][];
(2)I use Byte** when I send a pointer to an array.
(3)I guess you can using [][]... Sorry, I am not very sure... maybe a C
++ developer will answer better than me at these questions.

You won't be able to dual subscript, because the C++ compiler won't know the
dimensions. You'll need to calculate the offset yourself, as

array[col + row * colcount]
 
G

Guest

Thanks guys.
But I still can make it work...

I'm doing it as follow:

On the Unmanaged C++ side:
------------------------------------
int UnmanagedFunc(OUT IN BYTE** array, IN int arrayWidth, IN int arrayHeight)
{
// How to access any array element? For example: How do I get the element
[10][20] :

BYTE elementVal = array[10][20];

// - OR -

BYTE elementVal = array[10 * arrayWidth + 20];

return 0;
}

On the Managed C# side:
-------------------------------
[DllImport("Unmanaged.dll", EntryPoint = "UnmanagedFunc")]
public static extern int UnmanagedFunc(IntPtr ptrArray, int arrayWidth, int
arrayHeight,);
// - Or Maybe -
public static extern int UnmanagedFunc(ref byte[][] array, int arrayWidth,
int arrayHeight,);

private void ManagedMethod()
{
// Declare a jagged array.
byte[][] byteArray= new byte[20][];
// Setting the jagged array by getting a byte[] from another unmanaged DLL.
for( int ind = 0; ind < 20; ++ind )
{
byteArray[ind] = (byte[])AnotherUnmanagedDLL_GetByteArray();// returns
an Array encapsulating byte[]
}
// Can not use Marshal.Copy on a jagged array !!!
........ // ? ? ? ? ? ?
int res = UnmanagedFunc(byteArray, 20, byteArray[0].Length, defects);
}

--------------------------------------------------

This code does not work.

How do transfer the byteArray jagged array above to a unmanaged function so
it will be able to access any element of this array and change it, and when
this unmanaged function return I need to work with the changed array.

I'm the one that writes both the managed and unmanaged function, and I'm not
sure how to do it in both sides.

Can you help me or even maybe post some simple example?
 
B

Ben Voigt [C++ MVP]

Sharon said:
Thanks guys.
But I still can make it work...

I'm doing it as follow:

On the Unmanaged C++ side:
------------------------------------
int UnmanagedFunc(OUT IN BYTE** array, IN int arrayWidth, IN int
arrayHeight)
{
// How to access any array element? For example: How do I get the element
[10][20] :

BYTE elementVal = array[10][20];

// - OR -

BYTE elementVal = array[10 * arrayWidth + 20];

return 0;
}

On the Managed C# side:
-------------------------------
[DllImport("Unmanaged.dll", EntryPoint = "UnmanagedFunc")]
public static extern int UnmanagedFunc(IntPtr ptrArray, int arrayWidth,
int
arrayHeight,);
// - Or Maybe -
public static extern int UnmanagedFunc(ref byte[][] array, int
arrayWidth,
int arrayHeight,);

private void ManagedMethod()
{
// Declare a jagged array.
byte[][] byteArray= new byte[20][];
// Setting the jagged array by getting a byte[] from another unmanaged
DLL.
for( int ind = 0; ind < 20; ++ind )
{
byteArray[ind] = (byte[])AnotherUnmanagedDLL_GetByteArray();// returns
an Array encapsulating byte[]
}
// Can not use Marshal.Copy on a jagged array !!!
....... // ? ? ? ? ? ?
int res = UnmanagedFunc(byteArray, 20, byteArray[0].Length, defects);
}

--------------------------------------------------

This code does not work.

How do transfer the byteArray jagged array above to a unmanaged function
so
it will be able to access any element of this array and change it, and
when
this unmanaged function return I need to work with the changed array.

It's possible, by copying each sub array separately and building up an array
of IntPtr, then copying all back. Not going to be pretty or efficient.
I'm the one that writes both the managed and unmanaged function, and I'm
not
sure how to do it in both sides.

In that case, I highly recommend not using an unmanaged function at all.
Use C++/CLI instead, which can call native libraries the same way an
unmanaged function can, but also understands .NET types and arrays.
 
G

Guest

I'm afraid I can not do that.
I'm writing the unmanaged function only for testing reason. The actual
unmanaged function is written by the Algorithm group and must be done under
unmanaged environment for performance issues.

I still need to make work. But how?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top