Демаршалинг на вложена структура

Има две неуправляеми структури

typedef struct multipolynomial
{
    int N;
    int max_power;
    double* X;
    double** Y;
} multipolynomial;

typedef struct output
{
    double d;
    multipolynomial mp;
} output;

и съответните управлявани аналози

[StructLayoutAttribute(LayoutKind.Sequential)]
public unsafe class Multipolynomial
{
    public int n;
    public int max_power;
    public double* X;
    public double** Y;
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public unsafe struct Output
{
    public double d;
    public Multipolynomial mp;
}

И има родна функция

__declspec(dllexport) output __cdecl foo()
{
    output out;
    out.t = 1;
    return out;
}

с управляван подпис

[DllImport("kernel.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern Output foo();

който се срива тук

Output output = MathKernel.foo();

с обяснение "Подписът на типа на метода не е съвместим с PInvoke."

Моля, посочете какво се обърка?

PS: моля, обърнете внимание, че управляваният аналог за мултиполиномиална структура е клас


person kernelbug    schedule 05.10.2013    source източник


Отговори (1)


MSDN: P/Invoke не може да има типове без възможност за връщане стойност. Ето защо получавате грешката, която получавате. Освен това вашите управлявани дефиниции не съвпадат с вашите неуправляеми дефиниции. Неуправляемият output съдържа multipolynomial по стойност, но вашият управляван еквивалент го съдържа по препратка (освен това препратките към обекти не могат да бъдат прекратени). Управляваният Multipolynomial трябва да бъде структура и трябва да посочите [MarshalAs(UnmanagedType.Struct)] в полето mp — вижте MarshalAs вложена структура . Освен това не съм сигурен дали небезопасните указатели могат да бъдат прекъснати. Заменете ги с IntPtrs, докато тествате това, след което поставете указателите обратно.

person Anton Tykhyy    schedule 05.10.2013
comment
Благодаря ти! Ще пробвам това и ще ви кажа дали работи - person kernelbug; 06.10.2013
comment
Изглежда, че работи! Благодаря ти! Направих всички класове да бъдат структури и освен това работи за мен само с атрибут [StructLayoutAttribute(LayoutKind.Sequential)] - person kernelbug; 06.10.2013