使用 COM 互操作处理C++非托管代码中的 C# 事件
本文关键字:事件 非托管代码 C++ COM 互操作 处理 使用 | 更新日期: 2023-09-27 18:20:24
我有一个用C#编写的TcpSocketServer,我想在没有CLI的情况下在本机C++中使用它。该类在客户端连接/断开连接以及接收数据时引发事件。到目前为止,我让服务器工作并接受连接,但是我仍然无法发送/接收数据。
请注意,这是我需要使用的几个类之一,所以请不要建议我使用本机C++套接字。
(相关的(C# 代码如下:
[ComVisible(true)]
public delegate void TcpClientConnectedEventHandler(Socket s);
[ComVisible(true)]
public delegate void TcpClientDisconnectedEventHandler(EndPoint ep);
[ComVisible(true)]
public delegate void TcpDataReceivedEventHandler(TcpPacket p);
[ComVisible(true)]
[Guid("7cf49dcd-c11b-4e94-9f73-d5a24fe027c3")]
public interface ISocketTcpServer
{
event TcpClientConnectedEventHandler ClientConnected;
event TcpClientDisconnectedEventHandler ClientDisconnected;
event TcpDataReceivedEventHandler DataReceived;
[ComVisible(true)]
int SendToAll(byte[] buffer);
}
现在,在C++我有以下(相关(代码:
// Function Prototypes
void onClientConnected();
void onClientDisconnected();
void onDataReceived(ITcpPacket *packet);
VARIANT_BOOL started(ISocketTcpServer *server);
long send(ISocketTcpServer *server, char *s);
int main(int argc, char* argv[])
{
ISocketTcpServer *server = NULL;
_TcpDataReceivedEventHandler *dataReceivedPtr = NULL;
_TcpClientConnectedEventHandler *clientConnectedPtr = NULL;
_TcpClientDisconnectedEventHandler *clientDisconnectedPtr = NULL;
char sInput[1024];
std::cout << "C# Sockets Interop example.'r'n";
// Initialize COM.
CoInitialize(NULL);
// Create the interface pointers.
HRESULT hr = CoCreateInstance(__uuidof(SocketTcpServer), NULL,
CLSCTX_INPROC_SERVER, __uuidof(ISocketTcpServer), (void **)&server);
if((hr != S_OK) || (server == NULL))
{
std::cout << "Create instance failed'r'n";
CoUninitialize();
return 0;
}
// Configure TCP Server
server->put_Port(2000);
dataReceivedPtr = (_TcpDataReceivedEventHandler *)&onDataReceived;
clientConnectedPtr = (_TcpClientConnectedEventHandler *)&onClientConnected;
clientDisconnectedPtr =
(_TcpClientDisconnectedEventHandler *)&onClientDisconnected;
/* HERE IS WHERE I SET UP THE EVENTS */
server->add_ClientConnected(clientConnectedPtr);
server->add_ClientDisconnected(clientDisconnectedPtr);
server->add_DataReceived(dataReceivedPtr);
// Start TCP Server
std::cout << "Starting TCP Server on port 2000.'r'n";
server->Start();
while(!started(server)) Sleep(100);
while(started(server))
{
std::cin >> sInput;
send(server, sInput);
}
// Uninitialize COM.
CoUninitialize();
return 0;
}
long send(ISocketTcpServer *server, char *s)
{
long result = 0;
server->SendToAll((SAFEARRAY *) s, &result);
return result;
}
所有其他函数都有其定义并且工作正常,所以我没有包含它们。
主要问题是:必须如何声明将处理事件的函数才能使其工作。我认为它们不起作用,因为它们与关联的委托不匹配,但我无法访问 .NET Framework 的套接字和端点类。
还有方法
SendToAll(byte[] buffer):int
映射到函数
SendToAll(SAFEARRAY *buffer, long *pRetVal):HRESULT
但这可能是一个演员表问题。
你能给我的任何帮助或提示都会很有用。
提前祯炯。
假设您知道如何处理来自 VC++ 中标准 COM 组件的事件(我不是C++开发人员,所以我无法帮助该部分(,那么最好的办法是使用 ComSourceInterfacesAttribute 使您的 C# 看起来像一个标准 COM 组件。MSDN有一个简单的操作方法。
您的 C# 代码最终将如下所示(请注意,我删除了 [ComVisible(true)]
属性,因为如果您的程序集标有它,则不需要它们(:
public delegate void TcpClientConnectedEventHandler(Socket s);
public delegate void TcpClientDisconnectedEventHandler(EndPoint ep);
public delegate void TcpDataReceivedEventHandler(TcpPacket p);
public interface ISocketTcpServerEvents
{
void ClientConnected;
void ClientDisconnected;
void DataReceived;
}
[ComSourceInterfaces(typeof(ISocketTcpServerEvents))]
public class SocketTcpServer
{
public event TcpClientConnectedEventHandler ClientConnected;
public event TcpClientDisconnectedEventHandler ClientDisconnected;
public event TcpDataReceivedEventHandler DataReceived;
int SendToAll(byte[] buffer);
}