2013-08-02 10 views
6

Ich entwickle eine c .dll, die von einem C# -Programm zugegriffen werden sollte. Idealerweise sollte die .dll jede in C# definierte Struktur erhalten und etwas damit tun. Daher sind der Strukturtyp und die Größe für die C-DLL zunächst unbekannt. Ich war in der Lage, die Struktur durch die C extern-Funktion zu übergeben, und es wird angenommen, dass sie in Ordnung ist, aber gibt es eine Möglichkeit, die Größe und Eigenschaften dieser Empfangsstruktur herauszufinden? Gibt es eine Möglichkeit, über seine Mitglieder zu iterieren?iterieren über unbekanntes c struct übergeben von C#

Dies ist die C-Funktion für die DLL definiert

extern int __cdecl testCSharp(mystruct * Test){ 

//sizeof(Test) is 4, so it is ok 

for(int i=0;i < sizeof(Test) ; i++){ 

    char * value = (char*) Test; //This access the first element. 
    cout << value << endl; //Prints "some random string", so, it is received ok 
} 

return 1; 

}

Dies ist der C# -Code

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)] 
unsafe public struct myStruct{ 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value1; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value2; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value3; 
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)] 
    public string value4; 
}; 

[DllImport("SMKcomUploadDLL.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern int testCSharp(ref myStruct message); 

static void Main() 
{ 
    int result; 

    myStruct message = new myStruct(); 

    message.value1 = "Some randome string"; 
    message.value2 = "0"; 
    message.value3 = "olkujhikvb"; 
    message.value4 = "isabedfbfmlk"; 

    result = testCSharp(ref message); 
} 

Alle Typen String in C# sind, und es ist suppossed zu bleiben Sie so, also ist es das einzige, was ich über die Struktur weiß, die übergeben wird.

Irgendeine Idee?

Vielen Dank im Voraus

+0

Was meinst du mit * "sollte jede in C# definierte Struktur erhalten" *? C++ und C# sind statisch typisierte Sprachen. So ist jeder Typ zur Kompilierzeit auf beiden Seiten bekannt. Darüber hinaus sollten Definitionen von Typen auf beiden Seiten konsistent sein, so dass das Marshalling problemlos durchgeführt werden kann. – Nawaz

+2

Ich glaube nicht, dass der "sizeof" -Operator das tut, was er zu tun glaubt. 'sizeof (Test)' gibt 4 zurück, da die Größe eines Poiners 4 Bytes beträgt (auf einer 32-Bit-Maschine). Das bedeutet nicht, dass es 4 Punkte in Test gibt ... – PoByBolek

+0

@PoByBolek - Ich konnte nicht verstehen, was dieser Code macht, weil ich mir diese "einfache" Erklärung nicht vorstellen konnte. – SChepurin

Antwort

2

Wie Sie sie als ByValTStr mit einer Länge von 100 sind Rangier, ich bin nicht sicher, dass Sie als jede mehr arbeiten werden in der Lage, was Sie bereits haben (dh das erste Element).

aus der MSDN (here)

.NET Framework ByValTStr Typen verhalten sich wie im C-Stil, mit fester Größe Strings innerhalb einer Struktur (zB char s [5])

Wenn Sie stattdessen LPStr oder LPWStr Null-Terminierung verwendet haben, können Sie ihre Längen berechnen.