none
IntPtr[] RRS feed

  • Question

  • Hi,

    // original c function signature is foo(ULONG*, int, int*)
    [DllImport("sys.dll")]
    private static extern bool foo(IntPtr [] array, Int32 size,ref Int32 count);

    public void somefunc()
    {
       int actual_size=0;
       IntPtr [] array = new IntPtr[ARRAY_MAX_SIZE];
       foo(Array, ARRAY_MAX_SIZE, ref actual_size);
    }

    How do I iterate Array and output its data?

    Tuesday, March 25, 2008 1:25 PM

All replies

  • You can use the Marshal.Copy method.  Something like this maybe?

    Code Snippet

    [DllImport("sys.dll")]
            private static extern bool foo(IntPtr ptr, Int32 size, ref Int32 count);

            public void somefunc()
            {
                int actual_size = 0;

                IntPtr _ptr = Marshal.AllocHGlobal(ARRAY_MAX_SIZE);
                foo(ptr, ARRAY_MAX_SIZE, ref actual_size);
                int[] values = new int[actual_size];
                Marshal.Copy(ptr, values, 0, actual_size);
                Marshal.FreeHGlobal(ptr);
            }


    Wednesday, March 26, 2008 6:46 AM
  • Thanks for your prompt reply.

    I noticed you used

    Code Snippet

    IntPtr _ptr = Marshal.AllocHGlobal(ARRAY_MAX_SIZE);



    How is that different from what I did?

    Code Snippet

    IntPtr [] array = new IntPtr[ARRAY_MAX_SIZE];



    Im rather new at this marshaling stuff so please excuse my ignorance.

    Wednesday, March 26, 2008 7:29 AM
  • Why did you translate ULONG to IntPtr? Seems like a regular uint[]hould do it. And you can then iterate it with a regular loop.

     

     

    Wednesday, March 26, 2008 1:57 PM
  • Thanks for reply.

    Read somewhere that when marshalling any type of pointer (ULONG * in this case) I should use IntPtr.

    So you reckon I could use
    [code]
    DllImport("sys.dll")]
    private static extern bool foo(UInt [] array, Int32 size,ref Int32 count);

    given the following c signature
    bool foo(ULONG * arg1,int arg2,int * arg3)
    [/code]
    Wednesday, March 26, 2008 2:53 PM
  • Could you please clarify how exactly the arg1 will be used inside the C dll?
    Thursday, March 27, 2008 7:12 AM
  • Thanks for your reply.

    Inside the C function an internal objects is created, this object is queried for a list of id's. Then using a simpe for-loop the list of id's are copied from an internal list to the arg1.

    Does this answer your question? Not sure what kind of information you were looking for.



    Friday, March 28, 2008 7:52 AM
  • Inside the C function an internal objects is created, this object is queried for a list of id's. Then using a simpe for-loop the list of id's are copied from an internal list to the arg1.

    Could you please use some source code to illustrate all these processes?

    Monday, March 31, 2008 5:04 AM
  • Code Snippet

    extern "C"
    {
        __declspec(dllexport) bool GetIDList(ULONG * array,
                                            int size,
                                            int * count)
        {
            /* Init MFC */
            AFX_MANAGE_STATE(AfxGetStaticModuleState());

            bool bArraySize = false;   
            CInternalSet * Set = new CInternalSet();
            Configure(Set, CInternalType::ID);

            *count = Set->GetCount();
            if ((size / sizeof(ULONG)) >= *count)
            {
                for (int j=0; j < *count; j++)
                {   
                    array[j] = (*Set)[j];                   
                }
                bArraySize = true;
            }
            delete Set;
            return bArraySize;
        }
    }

    Monday, March 31, 2008 9:13 AM
  • OK; so the function interprets the size parameter as the array size in bytes, not the number of elements. That means the calling code should be

     

    uint[] array = new uint[ARRAY_MAX_SIZE];
    foo(array, ARRAY_MAX_SIZE * sizeof(uint), ref actual_size);

     

    Other than that, your code looks like it should work.

    Monday, March 31, 2008 9:22 AM