1

有人可以帮助我吗?我正在使用在我的 c# 项目(非托管 c++ dll)中注册为 COM 对象的 C++ dll。我在 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;
    }

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

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

更新:

嗨,汉斯,感谢您的帮助,我已经阅读了 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。该论坛上的最后一篇文章提供了一个示例,说明如何更改 il 而无需更改 DLL 项目(但我遇到了同样的问题,尽管我没有使用代理/存根 dll)。然后我尝试从存根/代理 dll 生成 Interop DLL 并改变它,但它给了我内存不足的异常。我还尝试将 CPP DLL 项目中的 Byte* 声明为 SAFEARRAY(BYTE) 但它给了我一个语法错误。

但是命运会让它注销所有 dll,清理等。我回到原来的 DLL,现在我继续遇到内存不足异常。非常有趣 xD ...会及时通知您。

4

1 回答 1

1

您的 com 对象方法采用指向 byte 的指针,但您传递的只是错误的字节 (nativeByte[0]) 的第一项,请像这样调用该方法

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

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

于 2013-06-19T16:19:13.277 回答