2011-04-13 13 views
5

Aktualnie mam program .NET inicjujący połączenie z serwerem. Czasami muszę wywołać specjalny niezarządzany kod C++, który wykorzystuje połączenie z serwerem.Przepuść gniazdo z .NET do niezarządzanego kodu C++

Jak przekazać i użyć połączenia z gniazdem .NET w niezarządzanym kodzie C++?

Z góry dzięki!

+0

Nie sądzę, że jest to obsługiwane po wyjęciu z pudełka. Jedyne co mogę sobie wyobrazić to to, że jeśli aplikacja C++ uruchomi proces, będzie w stanie odczytać pamięć aplikacji .NET, ale jest to zaawansowana terretoria. – NKCSS

+0

Może być na to inny sposób. Czy możesz podać wskaźnik delegata/funkcji do niezarządzanego kodu, który następnie wysyła dane do gniazda w kodzie .Net? – Nick

+0

Więc, Nick, jak to zrobić? – Trogvar

Odpowiedz

7

Klasa Socket ma właściwość Handle, której można użyć.

Socket.Handle @ MSDN

byłem sceptyczny, czy to będzie działać, ale udało mi się zmusić go do pracy bez problemów w ogóle.

Aby rozpocząć, zrobiłem niezarządzanego dll C++, aby eksportować jedną funkcję, która może zrobić coś z gniazdem. Oto funkcja, którą stworzyłem.

#include <WinSock.h> 

// This is an example of an exported function. 
extern "C" __declspec(dllexport) void __stdcall DoStuffWithSocket(DWORD sock) 
{ 
    const char *data = "woot\r\n"; 
    send((SOCKET)sock, data, strlen(data), 0); 
} 

Projekt wyprowadza dll o nazwie UnmanagedSocketHandler.dll, która jest wymieniona w bibliotece P/Invoke podpisu w następnym fragmencie.

Oto szybka i brudna aplikacja konsoli C# do wywoływania tej funkcji jako serwer.

using System.Net; 
using System.Net.Sockets; 
using System.Runtime.InteropServices; 

namespace SocketHandleShareTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      IPEndPoint ep = new IPEndPoint(IPAddress.Any, 5353); 
      Socket sListen = new Socket(AddressFamily.InterNetwork, 
             SocketType.Stream, ProtocolType.Tcp); 
      sListen.Bind(ep); 
      sListen.Listen(10); 
      Socket sClient = sListen.Accept(); 
      Console.WriteLine("DoStuffWithSocket() enter"); 
      Console.ReadLine(); 
      DoStuffWithSocket(sClient.Handle); 
      Console.WriteLine("DoStuffWithSocket() exit"); 
      Console.ReadLine(); 
      sClient.Close(); 
      sListen.Close(); 
      Console.WriteLine("Done."); 
      Console.ReadLine(); 
     } 

     [DllImport("UnmanagedSocketHandler.dll")] 
     static extern void DoStuffWithSocket(IntPtr sock); 
    } 
}  

Ostatni, szybka i brudna aplikacja kliencka C# do rozmowy z serwerem. Nie mogłem znaleźć żadnej dokumentacji na temat tego, dlaczego to działa, ale działa. Byłbym nieufny wobec tego, co próbujesz zrobić z gniazdem.

using System.Net; 
using System.Net.Sockets; 

namespace SocketHandleShareTestClient 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      byte[] buf = new byte[40]; 
      Socket s = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, ProtocolType.IP); 
      s.Connect("localhost", 5353); 
      int len = s.Receive(buf); 
      Console.WriteLine("{0} bytes read.", len); 
      if (len > 0) 
      { 
       string data = Encoding.ASCII.GetString(buf, 0, len); 
       Console.WriteLine(data); 
      } 
      s.Close(); 
      Console.ReadLine(); 
     } 
    } 
} 
+1

Nie sądziłem, że to możliwe ... bardzo fajna i dobra robota do testowania tego. +1 – NKCSS

2

Socket co oznacza System::Net::Sockets::Socket? Jeśli tak, przekaż Socket::Handle do niezarządzanego kodu.

+0

Należy zauważyć, że gniazdo zostanie zniszczone, gdy klasa Socket zostanie usunięta. – jgauffin

+0

Dobrze, lub sfinalizowane. Można mieć nadzieję, że funkcja niezarządzana jest synchroniczna ... – ildjarn

Powiązane problemy