我正在尝试编组从C到C#的结构,不知道从哪里开始

时间:2010-12-16 19:16:53

标签: c# c marshalling

我在C ++中的结构如下

 /* this structure contains the xfoil output parameters vs angle of attack */
    typedef struct xfoil_outputdata_struct
    {
     double *pAlfa;
     double *pCL;
     double *pCM;
     double *pCDi;
     double *pCDo;
     double *pCPmax;
     long nEntries;
    } XFOIL_OUTPUT_DATA;

    /* Here are the function prototypes for XFoil */
    __declspec(dllexport) XFOIL_OUTPUT_DATA *xfoilResults(); /* get output from xfoil */

我使用XFoilResults将此结构拉回到C#

我的DLL Imports语句如下:

 [DllImport("xfoilapi.dll")]
        public static extern void xfoilResults();

这是对的吗?我无法控制C ++代码。我只需要能够将结构拉入C#。我到目前为止的C#结构如下

[StructLayout(LayoutKind.Sequential)]
    public  struct xfoilResults
    {
     IntPtr pAlfa;
        IntPtr pCL;
        IntPtr pCM;
        IntPtr pCDi;
        IntPtr pCDo;
        IntPtr pCPmax;
     long nEntries;
    }

如何使用C ++代码中的数据填充此C#结构?

2 个答案:

答案 0 :(得分:2)

StructLayout必须在课堂上。

这应该可以解决问题:

[DllImport("xfoilapi.dll")]
public static extern IntPtr GetXfoilResults();

[StructLayout(LayoutKind.Sequential)]
public class XfoilResults
{
    IntPtr pAlfa;
    IntPtr pCL;
    IntPtr pCM;
    IntPtr pCDi;
    IntPtr pCDo;
    IntPtr pCPmax;
    int nEntries; // thanks to guys for reminding me long is 4 bytes
}

XfoilResults xf  ==  new XfoilResults();
Marshal.PtrToStructure(GetXfoilResults(), xf);

答案 1 :(得分:2)

首先,导入函数的返回类型应为IntPtr[MarshalAs(UnmanagedType.LPStruct)] xfoilResults_t

第二个重要的注意事项是,如果xfoilResults()正在分配和填充该结构中的数据,那么应该有一个第二个函数来清理该内存。您还必须导入 - 并在必要时调用它,否则最终会导致内存泄漏。

如果您要手动编组(即导入返回IntPtr),您应该可以使用

IntPtr retval = xfoilResults();
var results = (xfoilResults_t)Marshal.PtrToStructure(
                                         retVal, 
                                         typeof(xfoilResults_t));

//Do the following for each IntPtr field
double[] pCL = new double[results.nEntries];
Marshal.Copy(results.pCL, pCL, 0, results.nEntries);

//Don't forget to call whichever function is cleaning up the unmanaged memory.