JacoSchu
JacoSchu

Reputation: 11

Passing byte reference to unmanaged cpp COM dll from c#

could someone please help me. I am using a C++ dll that is registered as COM object in my c# project (unmanaged c++ dll). I am calling a function in the C++ dll that requires a BYTE* as one of the parameters (the BYTE* is a type defined as char*).

The DLL description states the following:

[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);

The c# code calling the function does the following:

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;
    }

The problem I am having is that the byte[] (nativeByte) is passed as a reference but only the first byte of the received array is correct (I had to use wireshark to see what data is being sent over the network). The receiving client just ignores the packet :( the remaining bytes sent differ each time.

The object browser shows that the function wants a "ref byte" to be passed, I don't know what I am doing wrong as the DLL is used in many other cpp projects without any issues. Any advise would be greatly appreciated :)

UPDATE:

Hi Hans, thanks for the help, I've read up on the SAFEARRAY declaration. I tried this post (see the last solution) 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. The last post on that forum gives an example of how to change the il without having to alter the DLL project (but I ran into the same issue, though I did not use the proxy/stub dll). I then tried to generate the Interop DLL from the stub/proxy dll and altererd that il, but it gave me Out of memory exceptions. I've also tried to declare the Byte* in the CPP DLL project as SAFEARRAY(BYTE) but it gives me a syntax error.

But as fate would have it unregistering all dlls, cleaning etc. I went back to the original DLL, an now I keep on getting Out of memory exceptions. Great fun xD ...will keep you posted.

Upvotes: 1

Views: 518

Answers (1)

srsyogesh
srsyogesh

Reputation: 609

Your com objects method take pointer to byte , but what you pass is only the first item of the byte (nativeByte[0]) which is wrong , call the method like this

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

ALso did you see in the intellisense what are the arguments the method is expecting when you type feg.SendPacket , which will help you in deciding whether to add ref keyword or not for arguments.

Upvotes: 1

Related Questions