2012-03-24 8 views
4

-In meinen C-Code habe ich eine Struktur, die viele unbekannte Größe Arrays in einer nicht verwalteten DLL (C-Code)Wie kann ich auf eine Struktur in csharp zugreifen, die dynamische Arrays aus einer nicht verwalteten DLL enthält?

-I müssen die Daten von eine Instanz diese Struktur gemarshallt über zu C#, die enthält ich später zurück an den unmanaged c code senden

-Ich muss nicht manipulieren diese Daten, sobald es zu csharp, halten Sie es nur/speichern Sie es für eine Weile (so dass es in einem Byte-Array bleiben kann).

-Ich möchte nicht das Schlüsselwort 'unsicher' verwenden, da es ein großes Projekt ist und dies ist nur ein kleines Stück und ich möchte nicht so kompilieren.

Ich habe versucht, es als lpArray Marshalling und alles sieht gut aus, aber wenn ich auf den Inhalt nach der Rückkehr zum csharp, es ist immer leer. Diese Art des Marshalling-Stils funktionierte für dynamische Arrays verschiedener Typen, nicht aber für die Struktur.

Die Suche im Internet ist leer und viel kompliziertere Szenarien als meine eigenen, aber wenn jemand einen solchen Link gesehen hat, bitte hier posten, ich wäre sehr dankbar!

Danke.

--update hier ist mehr oder weniger die Struktur meines Code:

C#:

[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
private static extern int W_Thread_Connect_NET(
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 100)] string IPAddress, 
    int DevicePort, 
    [MarshalAs(UnmanagedType.LPArray)] byte[] connectionHandle 
); 

//and call it like this, with an empty struc to be populated by c (can this be done? it is comming back without the data): 
byte[] myStrucParam= new byte[100]; 
int result = W_Thread_Connect_NET(myStrucParam, myParam1, myParam2, ...); 

c:

typedef struct myStructDef{ 
    char* myArray1, 
    char* myArray2, 
    int myInt1, 
    ... 
} mystrucObj, *pMystrucObj; 

//method that i am wanting to marshal the struct as a paramter here.. 
MYDLL_DLLIMPORT int APIENTRY W_Thread_Connect_NET(pMystrucObj strucReturn_handle, char * IPAddress, int DevicePort, ...) 
    { 
     //(omitted) 
    } 
+3

Zeigen Sie uns die C-Deklaration der Struktur und die C-Deklaration der nativen Funktion, die die Struktur empfängt. Dann können wir Ihnen den Pinvoke zeigen, den Sie brauchen. –

+0

Danke David - Ich habe ein bisschen Code hinzugefügt, ähnlich dem, an dem ich arbeite. Ich kann den eigentlichen Code hier natürlich nicht einfügen, weil er groß und chaotisch ist, und weil ich ihn nicht wirklich teilen darf. Lassen Sie mich wissen, wenn es andere Informationen gibt, die ich einschließen muss, um mich zu entweder einer Antwort oder einem Link für mehr Info zu leiten.! – Chris

+0

Woher kommt die Struktur? Wie sind die C-Strings zugeordnet? –

Antwort

2

Sie sagen, dass der C# -Code muss nicht manipuliere die Struktur. Das macht es ein ziemlich einfaches Problem zu lösen. Sie können den Strukturzeiger als undurchsichtigen Zeiger behandeln, also eine IntPtr.

allererst eine neue Funktion, um Ihre nativen Code hinzufügen:

pMystrucObj CreateStruct(void) 
{ 
    pMystrucObj res = malloc(sizeof(*res)); 
    return res; 
} 

Dann in Ihrem C# -Code Sie es so nennen:

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)] 
private static extern IntPtr CreateStruct(); 

Jetzt W_Thread_Connect_NET wie folgt erklären:

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)] 
private static extern int W_Thread_Connect_NET(
    IntPtr theStructPtr, 
    string IPAddress, 
    int DevicePort, 
    .... 
); 

Und nennen Sie es alles wie folgt:

Und natürlich wollen Sie eine weitere Funktion mit dem Namen DestroyStruct hinzufügen, um den Speicher der Struktur freizugeben, sobald Sie damit fertig sind.