2

Ok I've been trying to marshall a data structure that has this equivalent in C/C++ format:

Struct ResultsRecord
{

        int LengthOutMD; // this contains the size for the arrays below.


    float *OutMD;

    float *OutAxialLoad;
    float *OutNormalForce
}

This is the function that is contained in the unmanaged code inside a dll file:

typedef int (cdecl *ReadResultsTnDAnalysis) (wchar_t* ResultFileName, struct ResultsRecord* TnDResultsRecord);

Now here is my solution which does not work for now: because I can not find an easy way to marshall a pointer to the initial value of the array: the size of the arrays are unknown a priori.

public class APIforEngine
  {
        [DllImport("TnDAnalysisDLL.dll", EntryPoint = "ReadResultsTnDAnalysis", CallingConvention = CallingConvention.Cdecl  
        public static extern int ReadResultsTnDAnalysis(string resultFileName,
        ref TnDResultsRecord tnDResultsRecord);, CharSet = CharSet.Auto)]

  }

[StructLayout(LayoutKind.Sequential), Serializable]
public struct TnDResultsRecord
{

    public int LengthOutMD;


    [MarshalAs(UnmanagedType.LPArray)]
    public float[] OutMD;
    [MarshalAs(UnmanagedType.LPArray)]
    public float[] OutAxialLoad;
    [MarshalAs(UnmanagedType.LPArray)]
    public float[] OutNormalForce;
 }

Your help is well appreciated.

Right now I am thinking about consuming the dll in an intermediate C++ project transform the data into something easily read by C# and consume it in my C# solution. Even this route I will have to see if it is really feasible because for one I don't know how to consume it. in native c++ or use CLR? and if I use CLR do I use InterOpServices namespace classes or consume it using header file.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Amir Gasmi
  • 19
  • 3
  • Related: http://stackoverflow.com/a/11970209 – Robert Harvey Dec 18 '14 at 17:14
  • 1
    You can't convince the pinvoke marshaller to do it for you, no way to tell it how long the arrays are. Just do it yourself, declare the array members as IntPtr. And use Marshal.Copy() after the function call to copy the arrays. Do beware a memory management problem, in a case like this it is very unclear who is supposed to release the memory for the arrays. You can't. But for a "results" record you typically have to. Maybe you are supposed to pre-allocate the memory for the arrays, you *can* do that with Marshal.AllocHGlobal(). – Hans Passant Dec 18 '14 at 18:18

0 Answers0