none
Passing multi-dimensional array from C# to Win32 C++ dll? RRS feed

  • Question

  • hello

    I'm trying to pass multi-dimensional arrays from C# to un-managed WIN32 C++ dll - second parameter of each of the two functions exported below are meant to be OUTPUT parameter (memory allocated in C# however)

    MATLABGENERICDLL_API void GetCurves(char* strParam, double * myCurve)
    {
    for(int i=0; i<10; i++)
    {
    if(i>0) {
    myCurve[i] = 1.01 * Curve[i-1];
    } else {
    myCurve[i] = 0.5;
    }
    }
    return;
    }

    MATLABGENERICDLL_API void GetMatrix(char* strParam, double ** myMatrix)
    {
    try {
    for(int i=0; i<10; i++)
    {
    for(int j=0; j<10; j++)
    {
    myMatrix[i][j] = 0.25;
    }
    }
    } catch( ...)
    {
    throw;
    }

    return;
    }


    GetCurves executed successfully, but not GetMatrix.

    class Program
    {
    [DllImport(@"C:\MatlabGenericDll.dll")]
    private static extern string ToUpper2(string Src);

    [DllImport(@"C:\MatlabGenericDll.dll")]
    private static extern void GetCurves(string strParam, [In, Out] double[] myCurves);

    [DllImport(@"C:\MatlabGenericDll.dll")]
    private static extern void GetMatrix(string strParam, [In, Out] double[,] myMatrix);

    static void Main(string[] args)
    {
    string strTest = "abc";
    string strResult = null;

    double[] myCurve = null;
    double[,] myMatrix = null;

    try
    {
    strResult = ToUpper2(strTest);

    myCurve = new double[100];
    GetYieldCurves("AAA", myCurve); << For some reason, executed succssfully (Although I checked &myCurve - address seems to be different in C#/C++ layer so I really don't understand why it worked)
    myMatrix = new double[10, 10];
    GetMatrix("BBB", myMatrix); << System.AccessViolationException, complained saying memory probably corrupted.
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.ToString());
    }

    return;
    }
    }


    I'm not sure if I am doing right thing ... allocating memory from C# layer and if C# exe and C++ dll share same address space at all.

    My end goal is: I actually also need to pass, from c# exe to unmanaged C++ dll, a two-dimensional array of undetermined size of different column types (string, doubles, int, DateTime)

    Thanks!

    http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx
    • Edited by devvvy Thursday, July 30, 2009 6:01 AM
    Thursday, July 30, 2009 2:14 AM

Answers

  • Marshaling multi-dimensional arrays is not supported (see Default Marshaling for Arrays). You will have to do it by hand or as single-dimensional array.
    Learn more about marshaling in Interop Marshaling Overview. That will answer your question about address space in your managed(C#)/native(C++) components. It should also clarify how you can reach your end goal (by manual marshaling).

    -Karel
    • Marked as answer by eryang Wednesday, August 5, 2009 3:46 AM
    Friday, July 31, 2009 1:03 PM
    Moderator