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();
}
}
}
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
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
Więc, Nick, jak to zrobić? – Trogvar