Forum: PC-Programmierung Wrapper Marshalling-Problem


von Mario G. (suicided)


Lesenswert?

Hallo Forum,

ich schreibe momentan einen .NET-Wrapper für die Winsock2-Funktionen mit 
C++. Dort muss ich eine Struktur in eine Klasse umwandeln, was ansich 
auch funktioniert. Problematisch ist es aber bei folgender Variable:
1
char FAR  FAR **h_aliases;
Das habe ich in eine String-Liste 
(System::Collections::Generic::List<String>) umgewandelt, was im C++ 
Wrapper auch tadellos geschluckt wird. Verarbeite ich die Klasse jedoch 
in C#, meckert der Compiler "'...h_aliases' is not supportet by the 
language". ...was mir ziemlich unlogisch erscheint - wozu nimmt man denn 
.NET-Datentypen?
Hat vielleicht jemand hier eine Idee, wie man das in anderer Art und 
Weise wrappen könnte? Das ist halt alles ziemlich dynamisch - weder die 
Länge noch die Anzahl der Strings ist vorher bekannt.

Viele Grüße
mario

Die ursprüngliche Struktur:
1
typedef struct hostent {
2
  char FAR      *h_name;
3
  char FAR  FAR **h_aliases;
4
  short         h_addrtype;
5
  short         h_length;
6
  char FAR  FAR **h_addr_list;
7
} HOSTENT, *PHOSTENT, FAR *LPHOSTENT;
Meine dafür angelegte Klasse:
1
public ref class WS2_hostent {
2
public:
3
  String^ h_name;
4
  List<String^> h_aliases;
5
  Int16 h_addrtype;
6
  Int16 h_length;
7
  List<String^> h_addr_list;
8
9
  WS2_hostent();
10
  !WS2_hostent();
11
  ~WS2_hostent();
12
};
Die verarbeitende Funktion, welche aus C# aufgerufen wird:
1
Int32 WS2_Functions::gethostbyname(String^ name, WS2_hostent^ WS2_HostEnt) {
2
  hostent* hostEnt = ::gethostbyname((char*)(void*)Marshal::StringToHGlobalAnsi(name));
3
  WS2_HostEnt->h_name = String(hostEnt->h_name).ToString();
4
  while (*(hostEnt->h_aliases)) {
5
    WS2_HostEnt->h_aliases.Add(String(*hostEnt->h_aliases).ToString());
6
    hostEnt->h_aliases++;
7
  }
8
  WS2_HostEnt->h_addrtype = hostEnt->h_addrtype;
9
  WS2_HostEnt->h_length = hostEnt->h_length;
10
  while (*(hostEnt->h_addr_list)) {
11
    WS2_HostEnt->h_addr_list.Add(String(*hostEnt->h_addr_list).ToString());
12
    hostEnt->h_addr_list++;
13
  }
14
  return (hostEnt != NULL) ? WS2_Definitions::WS2_WSAOK : (Int32)WSAGetLastError();
15
}
Die Verwendung in C#, die fehlschlägt:
1
private void button3_Click(object sender, EventArgs e) {
2
  WS2_hostent hostEnt = new WS2_hostent();
3
  SocketFunctions.gethostbyname("www.google.de", hostEnt);
4
  foreach (String s in hostEnt.h_aliases) { // !!!
5
    textBox1.AppendText("\th_alias: " + s + "\r\n");
6
  }
7
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.