IJW: управляемая структура прокси? - PullRequest
3 голосов
/ 18 мая 2009

Я работаю над переносом некоторого кода C ++ на управляемый .NET. Мне нужно будет сохранить некоторый код C ++ в нативном виде и пытаться использовать подход IJW к нему. Я знаю, что можно объявить неуправляемую структуру, чтобы она правильно маршалировалась в код .NET, но компилятор C ++, похоже, этого не делает.

Например, у меня есть этот код (управляемый):

struct MyStruct
{
     int some_int;
     long some_long;
};

public ref class Class1
{
    static MyStruct GetMyStruct()
    {
        MyStruct x = { 1, 1 };
        return x;
    }
};

Он компилируется, но когда я смотрю на него с помощью рефлектора, код выглядит так:

public class Class1
{
    // Methods
    private static unsafe MyStruct GetMyStruct()
    {
        MyStruct x;
        *((int*) &x) = 1;
        *((int*) (&x + 4)) = 1;
        return x;
    }
}

[StructLayout(LayoutKind.Sequential, Size=8), NativeCppClass, 
                      MiscellaneousBits(0x41), DebugInfoInPDB]
internal struct
{
}

По сути, никакие поля в MyStruct не видны .NET. Есть ли способ сказать компилятору C ++ генерировать их?

При ответе, пожалуйста, учтите следующее: : Я знаю, как создать управляемый класс, который мог бы быть видимым для .NET Framework. Я НЕ заинтересован в этом. Я хочу, чтобы компилятор C ++ объявлял неуправляемую структуру таким образом, чтобы .NET это понимал, что-то вроде:

[StructLayout(LayoutKind::Sequential, blablabla ... )]
struct MyStruct
{
    [MarshalAs ....... ]
    System::Int32 some_int;
    [MarshalAs ....... ]
    System::Int32 some_long;
};

Ответы [ 2 ]

1 голос
/ 09 января 2012

Этот вопрос был просмотрен 194 раз за последние 2 года, без недостатка внимания. Возьмите отсутствие ответов как достаточное доказательство того, что это просто невозможно. Неуправляемая структура должна маршалировать , правила компоновки .NET для структур принципиально несовместимы с правилами компилятора C или C ++. Этот ответ содержит некоторую справочную информацию о том, почему .NET работает таким образом.

1 голос
/ 09 января 2012

Если вы хотите определить публичную структуру, видимую для приложений .NET, из управляемого кода C ++, вот способ сделать это (обратите внимание на ключевые слова 'public' и 'value'):

[StructLayout(LayoutKind::Sequential)]
public value struct MyStruct
{
    int some_int;
    long some_long;
};

Если вы хотите, чтобы неуправляемая структура перемещалась между C # и C / C ++, вам придется объявить ее с обеих сторон. Как это в C:

struct MyUnmanagedStruct
{
         int some_int;
         long some_long;
};

и так, скажем, в C #, например:

[StructLayout(LayoutKind.Sequential)]
struct MyUnmanagedStruct
{
    public int some_int;
    public long some_long; // or as int (depends on 32/64 bitness)
};

Вам необходимо убедиться, что поля в .NET совпадают с полями из C. Возможно, вы захотите использовать атрибуты StructLayout (в частности, Pack). См. Два учебника здесь: Учебник по структурам и здесь: Как выполнить: Маршалловские структуры с использованием PInvoke

...