【问题标题】:Passing byte reference to unmanaged cpp COM dll from c#从 c# 传递对非托管 c++ COM dll 的字节引用
【发布时间】:2013-06-19 15:46:43
【问题描述】:

有人可以帮助我吗?我正在使用在我的 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 项目中使用没有任何问题。任何建议将不胜感激:)

更新:

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

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

【问题讨论】:

  • 不应该是ref nativeByte 还是只是nativeByte 而不是ref nativeByte[0]?另外,IDL 函数原型中的ref 属性让我感到困惑。
  • 您的方法声明没有很好地通过类型库。那是因为您没有使用 SAFEARRAY,即自动化兼容的数组类型。幸存下来的只有 BYTE*,看起来像是通过引用传递给 Tlbimp.exe 的单个字节。修复它相当痛苦,您必须使用 ildasm.exe 反编译互操作库,编辑 .il 文件中的方法声明并将 humpty-dumpty 与 ilasm.exe 重新组合在一起。使用从等效 C# 方法获得的 IL 来了解如何编辑 .il 文件。

标签: c# c++ pointers dll reference


【解决方案1】:

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

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

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

【讨论】:

  • 我尝试了您的解决方案,但它只是给了我一个错误,说 Byte [] 无法转换为 ref Byte :(
猜你喜欢
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 2011-04-21
  • 2020-05-03
  • 2014-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多