Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Passing an int array by refеrence to a shell function - how?

Passing an int array by refеrence to a shell function - how?

Scheduled Pinned Locked Moved C#
comlinuxdata-structureshelptutorial
12 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J jjansen

    I assume your already familiar with using unmanaged code (Introp calls etc.) Try this: int[] MyArrayOfInts = ... fixed(int* p_MyArrayOfInts = MyArrayOfInts) { ThatFunction(p_MyArrayOfInts); } Good luck.

    I Offline
    I Offline
    iliyang
    wrote on last edited by
    #3

    OK, but the function prototype is: protected static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref int lParam) that is, I have to pass an integer, not an interger pointer...

    J 1 Reply Last reply
    0
    • I iliyang

      OK, but the function prototype is: protected static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref int lParam) that is, I have to pass an integer, not an interger pointer...

      J Offline
      J Offline
      jjansen
      wrote on last edited by
      #4

      iliyang wrote: that is, I have to pass an integer, not an interger pointer... The syntax is: lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) HDM_GETORDERARRAY, // message ID (WPARAM) wParam, // = (WPARAM) (int) iSize; (LPARAM) lParam // = (LPARAM) (LPINT) lpiArray; ); where lpiArray is: Pointer to an array of integers that receive the index values for items in the header. So you do have to pass an array (even if the array is only one element long). The pointer in the code of my previous post is merely a pointer to the FIRST integer in a row. From there the app can access the next integer, and the next, and so on. It will assume there are iSize integers in a row, starting at the address that is the pointer.

      I 1 Reply Last reply
      0
      • J jjansen

        iliyang wrote: that is, I have to pass an integer, not an interger pointer... The syntax is: lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) HDM_GETORDERARRAY, // message ID (WPARAM) wParam, // = (WPARAM) (int) iSize; (LPARAM) lParam // = (LPARAM) (LPINT) lpiArray; ); where lpiArray is: Pointer to an array of integers that receive the index values for items in the header. So you do have to pass an array (even if the array is only one element long). The pointer in the code of my previous post is merely a pointer to the FIRST integer in a row. From there the app can access the next integer, and the next, and so on. It will assume there are iSize integers in a row, starting at the address that is the pointer.

        I Offline
        I Offline
        iliyang
        wrote on last edited by
        #5

        OK, 10x a lot! It worked finde when I called the function like this: int[] MyArrayOfInts = ... fixed(int* p_MyArrayOfInts = MyArrayOfInts) { ThatFunction(*p_MyArrayOfInts); // not: ThatFunction(p_MyArrayOfInts); }

        J 1 Reply Last reply
        0
        • I iliyang

          OK, 10x a lot! It worked finde when I called the function like this: int[] MyArrayOfInts = ... fixed(int* p_MyArrayOfInts = MyArrayOfInts) { ThatFunction(*p_MyArrayOfInts); // not: ThatFunction(p_MyArrayOfInts); }

          J Offline
          J Offline
          jjansen
          wrote on last edited by
          #6

          Huh? :confused: That's not a pointer to an array you're putting in the function but the value of the first array element. Anyhow, I was going to recommend an alternative method. The Interop-call to SendMessage should look something like this: [DllImport("user32.dll"] public static extern int SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, IntPtr lParam); You can get an IntPtr to your array using Marshal.Copy(Int[] source, int startIndex, IntPtr destination, int length). I've never used Marshal.Copy before, so if you're decide to try it this way let me know how it turns out.

          I 1 Reply Last reply
          0
          • J jjansen

            Huh? :confused: That's not a pointer to an array you're putting in the function but the value of the first array element. Anyhow, I was going to recommend an alternative method. The Interop-call to SendMessage should look something like this: [DllImport("user32.dll"] public static extern int SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, IntPtr lParam); You can get an IntPtr to your array using Marshal.Copy(Int[] source, int startIndex, IntPtr destination, int length). I've never used Marshal.Copy before, so if you're decide to try it this way let me know how it turns out.

            I Offline
            I Offline
            iliyang
            wrote on last edited by
            #7

            Yes, I know that I'm passing the first element of the array, but I just tried and it worked fine :) The second method (with the IntPtr) I found ealier but I didn't know how to obtain an IntPtr object. I suppose with the IntPtr is better too. But how should I get an IntPtr object to copy the array into?

            J 1 Reply Last reply
            0
            • I iliyang

              Yes, I know that I'm passing the first element of the array, but I just tried and it worked fine :) The second method (with the IntPtr) I found ealier but I didn't know how to obtain an IntPtr object. I suppose with the IntPtr is better too. But how should I get an IntPtr object to copy the array into?

              J Offline
              J Offline
              jjansen
              wrote on last edited by
              #8

              Just make one: int[] MyArray = ... IntPtr MyPointer = IntPtr.Zero; // make and initialize Marshal.Copy(MyArray, 0, MyPointer, MyArray.Length); (Note: Don't confuse the marshal-call with the overload Marshal.Copy(IntPtr, int[], int, int) .)

              I 1 Reply Last reply
              0
              • J jjansen

                Just make one: int[] MyArray = ... IntPtr MyPointer = IntPtr.Zero; // make and initialize Marshal.Copy(MyArray, 0, MyPointer, MyArray.Length); (Note: Don't confuse the marshal-call with the overload Marshal.Copy(IntPtr, int[], int, int) .)

                I Offline
                I Offline
                iliyang
                wrote on last edited by
                #9

                Nope, Marshal.Copy throws a NullReference exception when passing a null (0) IntPtr object. So for now, the "mystical" solution works the best :rolleyes:

                J 1 Reply Last reply
                0
                • I iliyang

                  Nope, Marshal.Copy throws a NullReference exception when passing a null (0) IntPtr object. So for now, the "mystical" solution works the best :rolleyes:

                  J Offline
                  J Offline
                  jjansen
                  wrote on last edited by
                  #10

                  You're right, my mistake. I wrongly assumed that the Copy method returns a pointer to the array. On second thought this isn't what Copy does at all. Instead you have to allocate some space yourself using Marshal.AllocHGlobal with the appropriate number of bytes. This gives you a valid IntPtr. int Nr = ...; // number of elements in array int[] MyArray = new int[Nr]; IntPtr MyPtr = Marshal.AllocHGlobal(Nr * sizeof(int)) Then call SendMessage with MyPtr. Next use the Copy(IntPtr MyPtr, int[] MyArray, 0, MyArray.Length) method. Finally use Marshal.FreeHAlloc.

                  I 1 Reply Last reply
                  0
                  • J jjansen

                    You're right, my mistake. I wrongly assumed that the Copy method returns a pointer to the array. On second thought this isn't what Copy does at all. Instead you have to allocate some space yourself using Marshal.AllocHGlobal with the appropriate number of bytes. This gives you a valid IntPtr. int Nr = ...; // number of elements in array int[] MyArray = new int[Nr]; IntPtr MyPtr = Marshal.AllocHGlobal(Nr * sizeof(int)) Then call SendMessage with MyPtr. Next use the Copy(IntPtr MyPtr, int[] MyArray, 0, MyArray.Length) method. Finally use Marshal.FreeHAlloc.

                    I Offline
                    I Offline
                    iliyang
                    wrote on last edited by
                    #11

                    Well, this time works but the values returned are messed. But, you know, this does work fine: _columnOrder = new int[this.Columns.Count]; int size = 0; IntPtr pHeader = SendMessage(this.Handle, (int) Win32.Consts.LVM_GETHEADER, 0, ref size); SendMessage(pHeader, (int) Win32.Consts.HDM_GETORDERARRAY, _columnOrder.Length, ref _columnOrder[0]); See the ref _columnOrder[0] in the second SendMessage call ;)

                    J 1 Reply Last reply
                    0
                    • I iliyang

                      Well, this time works but the values returned are messed. But, you know, this does work fine: _columnOrder = new int[this.Columns.Count]; int size = 0; IntPtr pHeader = SendMessage(this.Handle, (int) Win32.Consts.LVM_GETHEADER, 0, ref size); SendMessage(pHeader, (int) Win32.Consts.HDM_GETORDERARRAY, _columnOrder.Length, ref _columnOrder[0]); See the ref _columnOrder[0] in the second SendMessage call ;)

                      J Offline
                      J Offline
                      jjansen
                      wrote on last edited by
                      #12

                      OK, good luck with your project.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups