2009-05-18 7 views
3

Ich arbeite an der Portierung einiger C++ - Code auf Managed .NET. Ich werde einige C++ - Code in nativer Form beibehalten und versuchen, einen IJW-Ansatz zu verwenden. Ich weiß, dass es möglich ist, eine nicht verwaltete Struktur zu deklarieren, so dass sie ordnungsgemäß in .NET-Code gemarshallt wird, aber der C++ - Compiler scheint es nicht zu tun.IJW: verwaltete Proxy-Struktur?

Zum Beispiel habe ich diesen Code haben (verwaltet):

struct MyStruct 
{ 
    int some_int; 
    long some_long; 
}; 

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

Es kompiliert, aber wenn ich sehe es Reflektor, Code sieht wie folgt aus:

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

Grundsätzlich keine Felder in MyStruct ist für .NET sichtbar. Gibt es eine Möglichkeit, dem C++ - Compiler mitzuteilen, dass er einen generiert?

Wenn Sie antworten, beachten Sie bitte diese: Ich weiß, wie Sie eine verwaltete Klasse erstellen, die für .NET Framework sichtbar sein könnte. Ich bin daran NICHT interessiert. Was ich will, ist für die C++ Compiler nicht verwaltete Struktur in einer Art und Weise zu erklären, dass .NET es verstehen, so etwas wie:

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

Antwort

1

Wenn Sie eine öffentliche Struktur sichtbar zu .NET-Anwendungen zu definieren, von C++ Code verwaltet , hier ist ein Weg, um es (man beachte die ‚Öffentlichkeit‘ und ‚Wert‘ keywords) zu tun:

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

Wenn Sie eine nicht verwaltete Struktur bewegt werden zwischen C# und C/C++, haben Sie erklären es auf beiden Seiten. Wie dies in C:

struct MyUnmanagedStruct 
{ 
     int some_int; 
     long some_long; 
}; 

und wie dies beispielsweise in C#, zum Beispiel:

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

Hier finden Sie die Felder in .NET Spiel sicherzustellen, müssen die Felder von C können Sie möchte StructLayout Attribute (insbesondere Pack) verwenden. Sehen Sie zwei Tutorials hier: Structs Tutorial und hier: How to: Marshal Structures Using PInvoke

+0

Ja, aber das macht die Struktur verwaltet. Die Frage bezieht sich speziell auf den Zugriff auf Member von nativen Strukturen in C#. – Derrick

+0

@Derrick - Hmmm ... es war mir nicht klar, jedenfalls habe ich meine Antwort aktualisiert. –

+0

Danke. So mache ich es jetzt. Die Verwendung eines Pakets von 1 auf beiden Seiten ergibt identische Speicherlayouts, was es mir ermöglicht, einen Zeiger auf die nicht gemankte C++/CLI-Struktur zu erhalten und sie in die C# -Struktur zu werfen. Die Schande hier, und ich denke, was der Fragesteller versucht zu bekommen, ist, dass es Code-Duplizierung gibt, die zu Problemen der Wartbarkeit führt. Sie könnten die Struktur auch zweimal in C++ als verwaltete und nicht verwaltete Version deklarieren und dort das Casting durchführen, das Sie zumindest von unsicheren Blöcken in C# entfernt. Ich denke, dass irgendeine Form der Codegenerierung die einzige Lösung sein kann. – Derrick

1

Diese Frage wurde 193 mal in den letzten 2 Jahren angesehen, kein Mangel an Aufmerksamkeit. Nehmen Sie den Mangel an Antworten als ausreichenden Beweis dafür, dass dies nicht möglich ist. Eine nicht verwaltete Struktur hat, die gemarshallt werden soll, die .NET-Layoutregeln für Strukturen sind grundsätzlich mit denen für einen C- oder einen C++ - Compiler nicht kompatibel. This answer bietet einige Hintergrundinformationen darüber, warum .NET auf diese Weise funktioniert.

+0

Aber ich kann eine Struktur in C# mit dem exakt gleichen Layout definieren und den Zeiger werfen. Es ist nur eine Schande, zwei identische Definitionen für die gleiche Struktur zu machen. Danke für den Link! – Derrick

+0

Das war der Punkt des Links, Sie können nicht tatsächlich eine Struktur in C# mit dem exakt gleichen Layout definieren. Sie können nur ein Layout angeben, das * nach dem Marshalling * gültig ist. Das tatsächliche Layout ist vollständig nicht erkennbar. –

Verwandte Themen