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

时间:2013-06-19 15:46:44

标签: c# c++ pointers dll reference

有人可以帮助我。我正在使用在我的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来查看通过网络发送的数据) 。接收客户端只是忽略了数据包:(每次发送的剩余字节都不同。

对象浏览器显示该函数需要传递“ref byte”,我不知道我做错了什么,因为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。该论坛上的最后一篇文章给出了一个如何在不必改变DLL项目的情况下更改il的示例(但我遇到了同样的问题,尽管我没有使用proxy / stub dll)。然后我尝试从存根/代理DLL和altererd生成Interop DLL,但它给了我内存异常。我还尝试将CPP DLL项目中的Byte *声明为SAFEARRAY(BYTE),但它给出了语法错误。

但是命运会让它取消注册所有的dll,清理等等。我回到原来的DLL,现在我继续得到内存异常。很有趣xD ...会让你发布。

1 个答案:

答案 0 :(得分:1)

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

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

你还在intellisense中看到当你输入feg.SendPacket时这个方法所期望的参数是什么,这将帮助你决定是否为参数添加ref关键字。