Passing dynamic 2d array to unmanaged c++ dll

F

fahd

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
 
A

Arne Vajhøj

fahd said:
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.

First: the above C++ is not a 2D array, but an array of arrays !
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?

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

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

#include <stdio.h>

__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[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 = Marshal.AllocHGlobal(m * sizeof(float));
Marshal.Copy(x, 0, slice, 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);
}
Marshal.FreeHGlobal(x);
}
public static void Main(string[] args)
{
float[][] x = new float[3][];
for(int i = 0; i < 3; i++)
{
x = new float[2];
for(int j = 0; j < 2; j++)
{
x[j] = (i + 1) * 10 + (j + 1);
}
}
IntPtr umx = UMC(x, 3, 2);
f(umx, 3, 2);
UMD(umx, 3, 2);
Console.ReadKey();
}
}
}
 

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