从c#传递字节引用到非托管cppcom dll

本文关键字:cppcom dll 引用 字节 | 更新日期: 2023-09-27 18:19:07

谁能帮帮我?我正在使用一个c++ dll,它在我的c#项目(非托管c++ dll)中注册为COM对象。我正在调用c++ dll中的一个函数,该函数需要BYTE*作为参数之一(BYTE*是定义为char*的类型)。

DLL描述如下:

[id(4),helpstring("Send packet via channel")] HRESULT  SendPacket([in] struct FEG_UNIQUE_ID *Destination, [in,ref,size_is(MaxBytes),length_is(MaxBytes)] BYTE *Data, [in] LONG MaxBytes, [out,retval] VARIANT_BOOL *Result);

调用该函数的c#代码执行以下操作:

public Boolean SendPacket(UInt64 destID, Byte[] data)
    {
        Byte [] temp = new Scrambler().scramble(data); //Scramble data to be sent
        byte[] nativeByte = new byte[temp.Length]; //Convert to native byte type
        for (int i = 0; i < temp.Length; i++)
            nativeByte[i] = (byte)temp[i]; 
        FEGClientModule.FEG_UNIQUE_ID UIdestID = new FEGClientModule.FEG_UNIQUE_ID();
        UIDHelper.SetIDLongLong(unchecked(destID), out UIdestID);
        bool result = feg.SendPacket(ref UIdestID, ref nativeByte[0], nativeByte.Length);
        return result;
    }

我遇到的问题是,字节[](nativeByte)作为参考传递,但只有接收数组的第一个字节是正确的(我不得不使用wireshark来查看正在通过网络发送的数据)。接收客户端直接忽略数据包:(每次发送的剩余字节不同。

对象浏览器显示该函数希望传递一个"ref字节",我不知道我做错了什么,因为DLL在许多其他cpp项目中使用而没有任何问题。如有任何建议,将不胜感激:)

更新:

你好Hans,谢谢你的帮助,我已经阅读了SAFEARRAY声明。我尝试了这个帖子(见最后一个解决方案)http://social.msdn.microsoft.com/Forums/vstudio/en-US/25ac7d0d-6fca-48e2-a022-bcc29d0a2908/can-you-tell-me-why-safearray-so-important-in-interface-method-definition。该论坛上的最后一篇文章给出了一个示例,说明如何在不更改DLL项目的情况下更改il(但我遇到了同样的问题,尽管我没有使用代理/存根DLL)。然后我试图从存根/代理DLL生成互操作DLL并更改该DLL,但它给了我内存异常。我还试图在CPP DLL项目中声明字节*为SAFEARRAY(Byte),但它给了我一个语法错误。

但命运会让它注销所有的dll,清洗等。我回到原来的DLL,现在我不断得到内存异常。太有趣了……我会随时通知你的。

从c#传递字节引用到非托管cppcom dll

你的com对象方法采取指针到字节,但你传递的只是字节的第一项(nativeByte[0]),这是错误的,调用这样的方法

    bool result = feg.SendPacket(ref UIdestID, ref nativeByte, nativeByte.Length);

当你输入feg时,你是否在智能感知中看到方法期望的参数是什么?SendPacket,它将帮助您决定是否为参数添加ref关键字。