Я пытаюсь упорядочить структуру из C в C #, не знаю, с чего начать - PullRequest
3 голосов
/ 16 декабря 2010

Моя структура в 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 следующий:1008 * Это правильно?Я не имею никакого контроля над кодом 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 ]

2 голосов
/ 16 декабря 2010

Во-первых, тип возвращаемой вами импортированной функции должен быть либо 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.
2 голосов
/ 16 декабря 2010

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);
...