Разупорядочение вложенной структуры

Есть две неуправляемые структуры

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: обратите внимание, что управляемый аналог для структуры Multipolynomial является классом.


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