Reputation: 1879
i wanna call a c++ function (in win32 .dll) by C#. the c++ function in like this:
bool pack(BYTE * messageFields[]);
the function wants to fill some data (eg. a string or byte[]) at some indexes of the input argument. so plz tell me how the marshaling should be in C#.NET? i tried many types but got errors or no effects to my parameter!
the C# code must open native .DLL :
[DllImport("c:\\theDllName.dll")]
public static extern bool pack( // what is here? )
Upvotes: 0
Views: 265
Reputation: 1993
System.Byte[] is what you are probably looking for.
Sorry didn'see you had BYTE* ...[].
Some code
extern "C" UNMANAGEDCPP_API int fnUnmanagedCpp(BYTE* test[], int nRows, int nCols)
{
//do stuff
std::cout << "called!" << std::endl;
for ( int i = 0; i < nRows; ++i )
{
for ( int j = 0; j < nCols; ++j )
{
std::cout << int ( test[i][j] ) << std::endl;
}
}
test[0][0] = 23;
return 0;
}
And in C#:
[DllImport("UnmanagedCpp.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int fnUnmanagedCpp(IntPtr[] buffer, int nRows, int nCols );
public static IntPtr[] Marshall2DArray(byte[][] inArray)
{
IntPtr[] rows = new IntPtr[inArray.Length];
for ( int i = 0; i < inArray.Length; ++i )
{
rows[i] = Marshal.AllocHGlobal(inArray[i].Length * Marshal.SizeOf(typeof(byte)));
Marshal.Copy( inArray[i], 0, rows[i], inArray[i].Length );
}
return rows;
}
public static void Copy2DArray( IntPtr[] inArray, byte[][] outArray )
{
Debug.Assert(inArray.Length == outArray.Length);
int nRows = Math.Min( inArray.Length, outArray.Length );
for (int i = 0; i < nRows; ++i)
{
Marshal.Copy(inArray[i], outArray[i], 0, outArray[i].Length);
}
}
public static void Free2DArray(IntPtr[] inArray)
{
for (int i = 0; i < inArray.Length; ++i)
{
Marshal.FreeHGlobal(inArray[i]);
}
}
static void Main(string[] args)
{
byte[][] bTest = new byte[2][] { new byte[2] { 1, 2 }, new byte[2] { 3, 4 } };
IntPtr[] inArray = Marshall2DArray(bTest);
fnUnmanagedCpp(inArray, 2, 2);
Copy2DArray(inArray, bTest);
Free2DArray(inArray);
System.Console.WriteLine(bTest[0][0]);
}
I hope this helps, maybe there is another better/simpler way to do this. Please note that the code is only for "illustration" and might contain bugs.
Basically one passes in an array of IntPtrs and manually marshals...
Upvotes: 1