none
How to Marshal the struct array to the pointer? RRS feed

  • Question

  • Greetings, 

    I am importing the C++ dll to send sms/mms message to the mobile device.

    With this dll, I can send sms to the multiple mobile devices, 

    but having difficulty in marshaling. 

    This is the example code in C++ 

    OBSIReceiver receivers[1];  
    strcpy_s(receivers[0].szName, CStringA(m_strReceiverName));
    strcpy_s(receivers[0].szPhoneNumber, CStringA(m_strReceiverPhone));
    msg.pReceivers = receivers;  
    msg.ulReceiverCount = _countof(receivers); 


    msg.pReceivers is the pointer of the receivers struct array, 

    so I need to marshal the struct array in C#, to use this dll in winform application. 

    This is my code that I have implemented with.

                OBSIMessage msg = new OBSIMessage();
                OBSIReceiver[] receivers = new OBSIReceiver[phoneNumberList.Count];
                OBSISendResult result = new OBSISendResult();

                
                msg.szSubject = strTextTitle;           //제목
                msg.szCallbackNumber = callbackNumber;  //회신 번호

                for (int i = 0; i < phoneNumberList.Count; i++)
                {
                    receivers[i].szName = receiverName;
                    receivers[i].szPhoneNumber = phoneNumberList[i];
                }

                msg.ulReceiverCount = (UInt32)phoneNumberList.Count;
                //Process of Marshalling, to pass the parameter to the C++ function.
                IntPtr[] ptrReceivers = new IntPtr[phoneNumberList.Count];
                for (int j = 0; j < phoneNumberList.Count; j++)
                {                
                    IntPtr pReceiver = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(OBSIReceiver)));
                    Marshal.StructureToPtr(receivers[j], pReceiver, false);
                    ptrReceivers[j] = pReceiver;
                }

                msg.pReceivers = ptrReceivers[0];

    but this code only works when phoneNumberList count is 1.

    What can I do?

    I wish someone can help me.

    Have a good day, and Thanks for the reading.

    Tuesday, April 30, 2019 2:26 AM

Answers

  • Not sure if it's related to the error, but the following line:

    IntPtr pReceiver = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(OBSIReceiver)));

    Shoulden't it be like the following?

    IntPtr pReceiver = Marshal.AllocHGlobal(Marshal.SizeOf(receivers[j]));

    ======

    And I think you possibly need to marshal the array itself with Marshal.AllocCoTaskMem() and do Marshal.Copy() as "Calling Functions" example code in here.

    • Marked as answer by behindname Thursday, June 27, 2019 7:44 AM
    Tuesday, April 30, 2019 3:54 AM
    Answerer

All replies

  • Not sure if it's related to the error, but the following line:

    IntPtr pReceiver = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(OBSIReceiver)));

    Shoulden't it be like the following?

    IntPtr pReceiver = Marshal.AllocHGlobal(Marshal.SizeOf(receivers[j]));

    ======

    And I think you possibly need to marshal the array itself with Marshal.AllocCoTaskMem() and do Marshal.Copy() as "Calling Functions" example code in here.

    • Marked as answer by behindname Thursday, June 27, 2019 7:44 AM
    Tuesday, April 30, 2019 3:54 AM
    Answerer
  • Thanks for the reply! but Marshal.Copy() is only allowed for int [], and I can not find other example for struct array...
    Tuesday, April 30, 2019 7:53 AM
  • I think maybe you can use an int[]/long[] to store .ToInt32()/.ToInt64() for the pReceiver, then use Marshal.Copy() on it.

    Afterall, it should store array of pointers to your structs, and those pointers are 32/64-bit values corresponding to bitness of your application.

    • Edited by cheong00Editor Tuesday, April 30, 2019 9:27 AM
    • Marked as answer by behindname Wednesday, May 1, 2019 2:29 AM
    • Unmarked as answer by behindname Thursday, June 27, 2019 7:44 AM
    Tuesday, April 30, 2019 9:26 AM
    Answerer
  • I just adapt your answer, 

    IntPtr pReceiver = Marshal.AllocHGlobal(Marshal.SizeOf(receivers[j]));

    This part, and now it works!!

    Great, Thanks a lot :)

    Thursday, June 27, 2019 7:45 AM