2011-04-13 47 views
5

Tôi hiện đang có chương trình .NET khởi tạo kết nối với máy chủ. Đôi khi tôi cần gọi một mã C++ không được quản lý đặc biệt, sử dụng kết nối đến máy chủ.Vượt qua ổ cắm từ .NET sang mã C++ không được quản lý

Cách chuyển và sử dụng kết nối ổ cắm từ .NET trong mã C++ không được quản lý?

Cảm ơn trước!

+0

Tôi không nghĩ rằng điều này được hỗ trợ ngoài hộp. Điều duy nhất tôi có thể tưởng tượng là nếu ứng dụng C++ khởi chạy quá trình, nó sẽ có thể đọc được bộ nhớ của ứng dụng .NET, nhưng đó là quy hoạch tiên tiến. – NKCSS

+0

Có thể có các cách khác để thực hiện việc này. Bạn có thể cung cấp một con trỏ đại biểu/hàm vào mã không được quản lý mà sau đó gửi dữ liệu lên socket trong mã .Net? – Nick

+0

Vì vậy, Nick, làm thế nào để làm điều này? – Trogvar

Trả lời

7

Lớp Socket có thuộc tính Handle, có thể được sử dụng.

Socket.Handle @ MSDN

tôi đã hoài nghi về việc liệu này sẽ làm việc, nhưng tôi đã có thể có được nó để làm việc với không phiền phức gì cả.

Để bắt đầu, tôi đã tạo một tệp C++ không được quản lý để xuất một hàm duy nhất có thể làm điều gì đó với một ổ cắm. Đây là hàm tôi đã tạo.

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

Dự án xuất ra một dll có tên UnmanagedSocketHandler.dll, là thư viện được đề cập trong chữ ký P/Invoke trong đoạn mã tiếp theo.

Đây là ứng dụng giao diện điều khiển C# nhanh và bẩn để gọi chức năng đó dưới dạng Máy chủ.

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

Cuối cùng, ứng dụng C# khách hàng nhanh chóng và bẩn để nói chuyện với máy chủ. Tôi không thể tìm thấy bất kỳ tài liệu nào về lý do tại sao nó hoạt động, nhưng nó hoạt động. Tôi sẽ cảnh giác về những gì bạn cố gắng làm với ổ cắm.

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

Tôi không nghĩ rằng điều này là có thể ... rất hay và làm việc tốt để thử nghiệm điều này. +1 – NKCSS

2

Socket có nghĩa là System::Net::Sockets::Socket? Nếu có, hãy chuyển Socket::Handle vào mã không được quản lý.

+0

Lưu ý rằng ổ cắm sẽ bị hủy khi xử lý lớp Socket. – jgauffin

+0

Phải hoặc đã hoàn tất. Người ta có thể hy vọng chức năng không được quản lý là đồng bộ ... – ildjarn

Các vấn đề liên quan