none
PInvoke, how to marshal "char * arr[]" ? RRS feed

  • Question

  • I have to create a managed wrapper for a native DLL that is used to interface with a RFID reader. In xxxx.h there's the folowing declaration for the function I need to import:


    Code Snippet

    apiStatus WINAPI CS_Class1Gen2Read(HANDLE hCom,unsigned char QValue,unsigned char FilterBitCount,unsigned char* Filter_Bits,unsigned char* TagId[],unsigned char *TotalTagCount);



    and the's an exaple how to call the function from eVC:


    Code Snippet

        unsigned char QValue=2,FilterBitCount=0,TotalTagCount;
        unsigned char Filter_Bits[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        unsigned char* TagId[16];
        unsigned char TagIdX[16][16];

        for (int i=0;i<16;i++)
        {
            TagId[i] = &TagIdX[i][16];
        }
       
        status = CS_Class1Gen2Read(g_hCom,QValue,FilterBitCount,Filter_Bits,TagId,&TotalTagCount);

        if ((status == ERR_NONE)&&(TotalTagCount>0))
            {
                MessageBeep(MB_ICONASTERISK);
                ViewTag(TagId,TotalTagCount);
            }



    how do write the function import in .Net?

    and  "char* TagId[16]" is meant to be a 256 Byte buffer or an array of 16 pointers pointing to 16 arrays of 16 Bytes?

    This is what I've come up with:
    Code Snippet

    [DllImport("xxxx.dll")]
    public static extern short  CS_Class1Gen2Read(IntPtr hCom, byte QValue, byte FilterBitCount, ref byte[] Filter_Bits, IntPtr TagId, ref byte TotalTagCount);


    The worst part of all is that I can't test my implementation one way or the other because the dll requires the reader wich I don't have but I still need to try to do an implementation that will hopefully work.

    Any advice will be much apreciated,
                    Thank you
    Thursday, March 27, 2008 5:03 PM

Answers

  •  

     

    Here is a good article on msdn about marshalling strings.  I think you might be able to use a stringbuilder but I am not really sure.  You can always use the Marshal.Copy method.

     

    IntPtr filterBytes = IntPtr.Zero;

    CS_Class1Gen2Read(hCom, QValue, FilterBitCount, ref ptr, TagId, ref TotalTagCount);

    byte[] values = new byte[TotalTagCount];

    Marshal.Copy(filterBytes, values, 0, values.Length);

     

     

    http://msdn2.microsoft.com/en-us/library/s9ts558h.aspx

    Thursday, March 27, 2008 6:01 PM

All replies

  •  

     

    Here is a good article on msdn about marshalling strings.  I think you might be able to use a stringbuilder but I am not really sure.  You can always use the Marshal.Copy method.

     

    IntPtr filterBytes = IntPtr.Zero;

    CS_Class1Gen2Read(hCom, QValue, FilterBitCount, ref ptr, TagId, ref TotalTagCount);

    byte[] values = new byte[TotalTagCount];

    Marshal.Copy(filterBytes, values, 0, values.Length);

     

     

    http://msdn2.microsoft.com/en-us/library/s9ts558h.aspx

    Thursday, March 27, 2008 6:01 PM
  • Hi Catalin,

    Please read the following article:
    http://blog.rednael.com/2008/08/29/MarshallingUsingNativeDLLsInNET.aspx

    It's an in depth article about marshalling between native code and managed code. It shows which types are interoperable, how to import a DLL, how to pass strings, how to pass structures and how to de-reference pointers.

    This answers all your questions.
    Tuesday, September 9, 2008 7:19 AM