首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用COM-Interop处理C++非托管代码中的C#事件

使用COM-Interop处理C++非托管代码中的C#事件
EN

Stack Overflow用户
提问于 2012-01-15 09:20:04
回答 1查看 3.2K关注 0票数 1

我有一个用C#编写的TcpSocketServer,我想在没有命令行界面的本地C++中使用它。该类在客户端连接/断开以及接收到数据时引发事件。直到现在,我让服务器工作并接受连接,但是我仍然不能发送/接收数据。

请注意,这是我需要使用的几个类之一,所以请不要建议我使用原生C++套接字。

(相关) C#代码如下:

代码语言:javascript
复制
[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++中,我有以下(相关)代码:

代码语言:javascript
复制
// 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框架的类Socket和EndPoint。

另外,该方法

代码语言:javascript
复制
SendToAll(byte[] buffer):int

映射到函数

代码语言:javascript
复制
SendToAll(SAFEARRAY *buffer, long *pRetVal):HRESULT

但这可能是一个cast问题。

你能给我的任何帮助或小费都是有用的。

提前做好准备。

EN

回答 1

Stack Overflow用户

发布于 2012-01-15 12:57:27

假设您知道如何处理来自VC++中标准COM组件的事件(我不是C++开发人员,所以我不能在这方面提供帮助),那么最好的做法是使您的C#看起来像是使用ComSourceInterfacesAttribute的标准COM组件。在这方面,MSDN有一个过于简单的How To

您的C#代码将如下所示(注意,我删除了[ComVisible(true)]属性,因为如果您的程序集用它标记,则这些属性是不必要的):

代码语言:javascript
复制
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);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8866840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档