2011-04-13 2 views
5

Attualmente ho un programma .NET che avvia una connessione a un server. A volte ho bisogno di chiamare uno speciale codice C++ non gestito, che utilizza la connessione al server.Pass socket da. NET a codice C++ non gestito

Come passare e utilizzare la connessione socket da .NET nel codice C++ non gestito?

Grazie in anticipo!

+0

Non credo che questo sia supportato immediatamente. L'unica cosa che posso immaginare è che se l'applicazione C++ lanciasse il processo, sarebbe in grado di leggere la memoria dell'app .NET, ma questa è terretoria avanzata. – NKCSS

+0

Potrebbero esserci altri modi per farlo. Potresti fornire un puntatore delegato/funzione al codice non gestito che poi invia i dati sul socket nel codice .Net? – Nick

+0

Quindi, Nick, come si fa? – Trogvar

risposta

7

La classe Socket ha la proprietà Handle che potrebbe essere utilizzata.

Socket.Handle @ MSDN

ero scettico sul fatto che questo avrebbe funzionato, ma ero in grado di farlo funzionare senza alcun problema a tutti.

Per iniziare, ho creato una dll C++ non gestita per esportare una singola funzione che può fare qualcosa con un socket. Ecco la funzione che ho creato.

#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); 
} 

Il progetto emette una dll di nome UnmanagedSocketHandler.dll, che è la biblioteca menzionato nel P/Invoke firma nel prossimo snippet.

Ecco un'app per console C# veloce e sporca per chiamare quella funzione come server.

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); 
    } 
}  

Infine, un'app client C# veloce e sporca per parlare al server. Non sono riuscito a trovare alcuna documentazione sul perché funzioni, ma funziona. Sarei cauto su ciò che provi a fare con la presa.

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

Non pensavo che fosse possibile ... molto bello e buon lavoro per testarlo. +1 – NKCSS

2

Socket significato System::Net::Sockets::Socket? In tal caso, passare Socket::Handle al codice non gestito.

+0

Si noti che il socket verrà distrutto quando viene eliminata la classe Socket. – jgauffin

+0

Giusto o finalizzato. Si può sperare che la funzione non gestita sia sincrona ... – ildjarn