2009-05-18 5 views
3

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

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

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; 
}; 

ответ

1

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

[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). См. Два учебника здесь: Structs Tutorial и здесь: How to: Marshal Structures Using PInvoke

+0

Да, но это делает структуру управляемой. Речь идет, в частности, о доступе к членам родных структур на C#. – Derrick

+0

@Derrick - Хммм ... мне это было не совсем понятно, так или иначе, я обновил свой ответ. –

+0

Спасибо. Я так делаю сейчас. Используя пакет из 1 с обеих сторон, вы получаете одинаковые макеты памяти, что позволяет мне получить указатель на неименованную структуру C++/CLI и передать ее структуре C#. Позор здесь, и я думаю, что автор вопроса пытался понять, что существует дублирование кода, что приводит к проблемам с ремонтопригодностью. Вы также можете объявить структуру дважды в C++ как управляемую и неуправляемую версию и сделать кастинг там, который по крайней мере уберет вас от небезопасных блоков на C#. Я думаю, что некоторая форма генерации кода может быть единственным решением. – Derrick

1

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

+0

Но я могу определить структуру в C# с тем же самым макетом и нанести указатель. Кажется, что стыдно иметь два идентичных определения для одной и той же структуры. Спасибо за ссылку! – Derrick

+0

Это была ссылка на ссылку, вы не можете определить структуру на C# с тем же самым макетом. Вы можете указать только допустимый макет * после маршалинга *. Фактический макет полностью неизвестен. –

Смежные вопросы