.NET Framework - Passing dynamic 2d array to unmanaged c++ dll

Asked By fahd
14-Dec-07 02:04 AM
Hi,

I'm trying to communicate with an unmanaged c++ dll that takes two 2d
float arrays, one as input with data in it and the other will have the
result of the operation in it as follows:

bool Evaluate(float** input,float** output,int nFrames, int
featureWidth);

note: nFrames and featureWidth will determine the sizes of input and
output arrays in the c++ code.


Using this method in c# requires you to use float multidimensional
arrays. However I keep on getting exceptions thrown by the dll while
the same code works fine in a normal console application!

Trying to debug the dll as much as i can i figured out that the arrays
are not being passed correctly. can anybody help me out here, how
would I pass a 2 dimentional array to unmanaged c++ function?

Thanks
System.Runtime.InteropServices
(1)
Marshal.AllocHGlobal
(1)
Marshal.FreeHGlobal
(1)
Console.ReadKey
(1)
Marshal.SizeOf
(1)
AllocHGlobal
(1)
FreeHGlobal
(1)
DllImport
(1)
  arn replied...
23-Dec-07 03:22 PM
First: the above C++ is not a 2D array, but an array of arrays !


I seems as if .NET does not want to marshal an array of arrays
automatically.

So the only solution I can come up with is the rather complex
code attached below.

Arne

===============================================


__declspec(dllexport) void f(float **x, int n, int m)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++) printf(" %8.2f", x[i][j]);
printf("\n");
}
}

using System;
using System.Runtime.InteropServices;

namespace E
{
public class Program
{
[DllImport(@"C:\twodim.dll")]
private static extern void f(IntPtr x, int n, int m);
private static IntPtr UMC(float[][] x, int n, int m)
{
IntPtr[] slice = new IntPtr[n];
for(int i = 0; i < n; i++)
{
slice[i] = Marshal.AllocHGlobal(m * sizeof(float));
Marshal.Copy(x[i], 0, slice[i], m);
}
IntPtr res = Marshal.AllocHGlobal(n *
Marshal.SizeOf(typeof(IntPtr)));
Marshal.Copy(slice, 0, res, 3);
return res;
}
private static void UMD(IntPtr x, int n, int m)
{
IntPtr[] slice = new IntPtr[n];
Marshal.Copy(x, slice, 0, n);
for(int i = 0; i < n; i++)
{
Marshal.FreeHGlobal(slice[i]);
}
Marshal.FreeHGlobal(x);
}
public static void Main(string[] args)
{
float[][] x = new float[3][];
for(int i = 0; i < 3; i++)
{
x[i] = new float[2];
for(int j = 0; j < 2; j++)
{
x[i][j] = (i + 1) * 10 + (j + 1);
}
}
IntPtr umx = UMC(x, 3, 2);
f(umx, 3, 2);
UMD(umx, 3, 2);
Console.ReadKey();
}
}
}
Create New Account
help
sie auch im Explorer dargestellt wird - also: "dingsbums an 'diesemundjenenRechner'" ? Danke Michaela C# - German Discussions System.Runtime.InteropServices.Marshal.FreeHGlobal (1) NetworkDrive.ROOT.CIMV2 (1) System.Runtime.InteropServices.Marshal.SizeOf (1) ROOT.CIMV2.Win32 (1) System.Runtime.InteropServices.DllImport (1) System.Runtime.InteropServices
C# interop console test app using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace InteropTest { [StructLayout(LayoutKind.Explicit)] public struct my_subbuffer_t { [FieldOffset(0)] public int format; } [StructLayout(LayoutKind c * ** ** * ** * Start of Program.cs * ** * using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace InteropTest { [StructLayout(LayoutKind.Explicit)] public struct my_subbuffer_t { [FieldOffset(0)] public int format; } [StructLayout(LayoutKind my_buffer_t(); buf.count = 1; my_subbuffer_t[] subbuf = new my_subbuffer_t[1]; subbuf[0].format = 1; IntPtr pBuf = Marshal.AllocHGlobal( Marshal.SizeOf(buf) + Marshal.SizeOf(typeof(my_subbuffer_t)) ); buf.bufs = Marshal.AllocHGlobal( Marshal.SizeOf( typeof(my_subbuffer_t
IStream.Read() .NET Framework Hi, I have a problem using System.Runtime.InteropServices.ComTypes.IStream. Sample using the Read() method: if (IStreamObject ! = null) { IntPtr readBytes = IntPtr.Zero; IStreamObject msdn2.microsoft.com / en-us / library / aa380011.aspx http: / / msdn2.microsoft.com / en-us / library / system.runtime.interopservices.comtypes.istream.read.aspx Note this: For more information, see the existing documentation for ISequentialStream nor on MSDN nor in the current Windows SDK docs. The IStream.Read docs in System.Runtime.InteropServices.ComTypes does not mention NULL to be allowed, now if you do as the
10 214 379 520" is this information which I need in my scripts. Powershell Discussions System.Runtime.InteropServices.Marshal (1) System.IO.DriveInfo (1) Log Parser (1) StringWithNumber.Length (1) MyGetDiskFreeSpaceEx (1) LpTotalNumberOfFreeBytes dll")] public static extern bool GetDiskFreeSpaceEx( string lpDirectoryName, IntPtr lpFreeBytesAvailable, IntPtr lpTotalNumberOfBytes, IntPtr lpTotalNumberOfFreeBytes ); $fba = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20); $tnb = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20); $nfb = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(20