API - CopyMemory

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dennis

    API - CopyMemory

    I am trying to use CopyMemory to copy arrays as follows:

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMem ory" (ByVal
    pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)

    dim kin(11) as Integer
    dim kout(11) as Integer

    kin(1)= 1 'set values for two elements to see if Kout is the same
    kin(5) = 5

    CopyMemory(kout (0), kin(0), 48)

    It compiles and runs but all I get in Kout is "0" for all elements.

    --
    Dennis in Houston
  • Al Reid

    #2
    Re: API - CopyMemory

    "Dennis" <Dennis@discuss ions.microsoft. com> wrote in message
    news:56EB7C46-010F-4B0C-A70E-55F9BB89321F@mi crosoft.com...[color=blue]
    >I am trying to use CopyMemory to copy arrays as follows:
    >
    > Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMem ory" (ByVal
    > pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)
    >
    > dim kin(11) as Integer
    > dim kout(11) as Integer
    >
    > kin(1)= 1 'set values for two elements to see if Kout is the same
    > kin(5) = 5
    >
    > CopyMemory(kout (0), kin(0), 48)
    >
    > It compiles and runs but all I get in Kout is "0" for all elements.
    >
    > --
    > Dennis in Houston[/color]

    Try changing Long to Integer in the API declare. Looks like a VB6
    declaration. VB6 Long = VB.Net Integer

    --
    Al Reid


    Comment

    • Dennis

      #3
      Re: API - CopyMemory

      Tried that, no change. I found an example on the web that timed the various
      methods of copying arrays, i.e., for loop, assignment, and CopyMemory written
      for vb.net. It doesn't work either as it only copies zeros. The author
      apparently didn't test it by actually putting values in the source array.
      --
      Dennis in Houston


      "Al Reid" wrote:
      [color=blue]
      > "Dennis" <Dennis@discuss ions.microsoft. com> wrote in message
      > news:56EB7C46-010F-4B0C-A70E-55F9BB89321F@mi crosoft.com...[color=green]
      > >I am trying to use CopyMemory to copy arrays as follows:
      > >
      > > Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMem ory" (ByVal
      > > pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)
      > >
      > > dim kin(11) as Integer
      > > dim kout(11) as Integer
      > >
      > > kin(1)= 1 'set values for two elements to see if Kout is the same
      > > kin(5) = 5
      > >
      > > CopyMemory(kout (0), kin(0), 48)
      > >
      > > It compiles and runs but all I get in Kout is "0" for all elements.
      > >
      > > --
      > > Dennis in Houston[/color]
      >
      > Try changing Long to Integer in the API declare. Looks like a VB6
      > declaration. VB6 Long = VB.Net Integer
      >
      > --
      > Al Reid
      >
      >
      >[/color]

      Comment

      • Jack Russell

        #4
        Re: API - CopyMemory

        Dennis wrote:
        [color=blue]
        > Tried that, no change. I found an example on the web that timed the various
        > methods of copying arrays, i.e., for loop, assignment, and CopyMemory written
        > for vb.net. It doesn't work either as it only copies zeros. The author
        > apparently didn't test it by actually putting values in the source array.[/color]
        I would have the that you should be passing by ref not by val but ....

        Comment

        • Herfried K. Wagner [MVP]

          #5
          Re: API - CopyMemory

          "Dennis" <Dennis@discuss ions.microsoft. com> schrieb:[color=blue]
          > CopyMemory(kout (0), kin(0), 48)
          >
          > It compiles and runs but all I get in Kout is "0" for all elements.[/color]

          I am curious why you would want to use 'CopyMemory'. You may want to use
          'Buffer.BlockCo py' instead, which is pretty fast.

          --
          M S Herfried K. Wagner
          M V P <URL:http://dotnet.mvps.org/>
          V B <URL:http://classicvb.org/petition/>

          Comment

          • Dragon

            #6
            Re: API - CopyMemory

            Dennis,

            First, pDst and pSrc should be declared as ByRef. They are pointers, and
            passing pointers ByVal doesn't make much sense.
            Second, their type must match the type of an array.

            So, your declatation should look like:

            ~
            Declare Sub CopyMemory Lib "kernel32.d ll" Alias "RtlMoveMem ory" ( _
            ByRef Destination As Integer, _
            ByRef Source As Integer, _
            ByVal Length As Integer _
            )
            ~

            Third, you can declare them as arrays, so it will be:

            ~
            Declare Sub CopyMemory Lib "kernel32.d ll" Alias "RtlMoveMem ory" ( _
            <MarshalAs(Unma nagedType.LPArr ay)> ByVal Destination() As
            Integer, _
            <MarshalAs(Unma nagedType.LPArr ay)> ByVal Source() As Integer, _
            ByVal Length As Integer _
            )
            ~

            Fourth, why don't you use the Array.Copy method?

            Roman

            "Dennis" <Dennis@discuss ions.microsoft. com> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
            ÓÌÅÄÕÀÝÅÅ: news:56EB7C46-010F-4B0C-A70E-55F9BB89321F@mi crosoft.com...[color=blue]
            > I am trying to use CopyMemory to copy arrays as follows:
            >
            > Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMem ory"[/color]
            (ByVal[color=blue]
            > pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)
            >
            > dim kin(11) as Integer
            > dim kout(11) as Integer
            >
            > kin(1)= 1 'set values for two elements to see if Kout is the same
            > kin(5) = 5
            >
            > CopyMemory(kout (0), kin(0), 48)
            >
            > It compiles and runs but all I get in Kout is "0" for all elements.
            >
            > --
            > Dennis in Houston[/color]


            Comment

            • Dennis

              #7
              Re: API - CopyMemory

              Thanks for the corrections to my code. You are absolutely correct in that I
              need byRef. However, on the type in the declaration of CopyMemory, when
              passed by reference, isn't an integer or long passed to the Com routine as
              the address? For example, if my array is of type byte and I pass the array
              by reference, what is actually passed...isn't it a 4 byte address?

              As for using Array.CopyTo, in the end, I actually will be using CopyMemory
              to copy a structure into an array for use with another com object.
              --
              Dennis in Houston


              "Dragon" wrote:
              [color=blue]
              > Dennis,
              >
              > First, pDst and pSrc should be declared as ByRef. They are pointers, and
              > passing pointers ByVal doesn't make much sense.
              > Second, their type must match the type of an array.
              >
              > So, your declatation should look like:
              >
              > ~
              > Declare Sub CopyMemory Lib "kernel32.d ll" Alias "RtlMoveMem ory" ( _
              > ByRef Destination As Integer, _
              > ByRef Source As Integer, _
              > ByVal Length As Integer _
              > )
              > ~
              >
              > Third, you can declare them as arrays, so it will be:
              >
              > ~
              > Declare Sub CopyMemory Lib "kernel32.d ll" Alias "RtlMoveMem ory" ( _
              > <MarshalAs(Unma nagedType.LPArr ay)> ByVal Destination() As
              > Integer, _
              > <MarshalAs(Unma nagedType.LPArr ay)> ByVal Source() As Integer, _
              > ByVal Length As Integer _
              > )
              > ~
              >
              > Fourth, why don't you use the Array.Copy method?
              >
              > Roman
              >
              > "Dennis" <Dennis@discuss ions.microsoft. com> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌà  × ÎÏ×ÏÓÔÑà ˆ
              > ÓÌÅÄÕÀÝà …Ã…: news:56EB7C46-010F-4B0C-A70E-55F9BB89321F@mi crosoft.com...[color=green]
              > > I am trying to use CopyMemory to copy arrays as follows:
              > >
              > > Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMem ory"[/color]
              > (ByVal[color=green]
              > > pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)
              > >
              > > dim kin(11) as Integer
              > > dim kout(11) as Integer
              > >
              > > kin(1)= 1 'set values for two elements to see if Kout is the same
              > > kin(5) = 5
              > >
              > > CopyMemory(kout (0), kin(0), 48)
              > >
              > > It compiles and runs but all I get in Kout is "0" for all elements.
              > >
              > > --
              > > Dennis in Houston[/color]
              >
              >
              >[/color]

              Comment

              • Dennis

                #8
                Re: API - CopyMemory

                Thanks, you are correct in that I should be using byref. I was trying code
                from an example I got from the net (it didn't work either) and that's why.
                --
                Dennis in Houston


                "Jack Russell" wrote:
                [color=blue]
                > Dennis wrote:
                >[color=green]
                > > Tried that, no change. I found an example on the web that timed the various
                > > methods of copying arrays, i.e., for loop, assignment, and CopyMemory written
                > > for vb.net. It doesn't work either as it only copies zeros. The author
                > > apparently didn't test it by actually putting values in the source array.[/color]
                > I would have the that you should be passing by ref not by val but ....
                >[/color]

                Comment

                • Dennis

                  #9
                  Re: API - CopyMemory

                  Thanks Herfried but in the end, I want to copy a structure into an array
                  contained in another array for passing to another com object. That's why I
                  didn't use Buffer class.
                  --
                  Dennis in Houston


                  "Herfried K. Wagner [MVP]" wrote:
                  [color=blue]
                  > "Dennis" <Dennis@discuss ions.microsoft. com> schrieb:[color=green]
                  > > CopyMemory(kout (0), kin(0), 48)
                  > >
                  > > It compiles and runs but all I get in Kout is "0" for all elements.[/color]
                  >
                  > I am curious why you would want to use 'CopyMemory'. You may want to use
                  > 'Buffer.BlockCo py' instead, which is pretty fast.
                  >
                  > --
                  > M S Herfried K. Wagner
                  > M V P <URL:http://dotnet.mvps.org/>
                  > V B <URL:http://classicvb.org/petition/>
                  >
                  >[/color]

                  Comment

                  • Dragon

                    #10
                    Re: API - CopyMemory

                    "Dennis" <Dennis@discuss ions.microsoft. com> ñîîáùèë/ñîîáùèëà â íîâîñòÿõ
                    ñëåäóþùåå: news:3280A299-60AD-41B2-ABB4-D3C25007256F@mi crosoft.com...[color=blue]
                    > Thanks for the corrections to my code. You are absolutely correct in[/color]
                    that I[color=blue]
                    > need byRef. However, on the type in the declaration of CopyMemory,[/color]
                    when[color=blue]
                    > passed by reference, isn't an integer or long passed to the Com[/color]
                    routine as[color=blue]
                    > the address? For example, if my array is of type byte and I pass the[/color]
                    array[color=blue]
                    > by reference, what is actually passed...isn't it a 4 byte address?[/color]

                    First, CopyMemory isn't a COM routine. 8=]

                    Yes, passing ByRef means passing IntPtr (platform-dependent integer)
                    value which represents address of a variable, so if you wanted to
                    specify an address (ByVal), you should declare it as IntPtr. But when
                    you declare parameter ByRef you specify a type of variable itself, not
                    type of pointer to it, don't you?

                    If you pass an array by reference you get garbage 8=]. You can either
                    pass its first element by reference, or pass the whole array by value.
                    You will get the same result though.
                    [color=blue]
                    >
                    > As for using Array.CopyTo, in the end, I actually will be using[/color]
                    CopyMemory[color=blue]
                    > to copy a structure into an array for use with another com object.[/color]

                    You can use Marshal.Structu reToPtr() method for this, for example:

                    ~
                    Dim a(Marshal.SizeO f(GetType(Decim al)) - 1) As Byte
                    Marshal.Structu reToPtr(23568.2 3573D,
                    Marshal.UnsafeA ddrOfPinnedArra yElement(a, 0), False)
                    Stop
                    ~
                    [color=blue]
                    > --
                    > Dennis in Houston
                    >[/color]

                    Roman


                    Comment

                    • Jay B. Harlow [MVP - Outlook]

                      #11
                      Re: API - CopyMemory

                      Dennis,
                      Rather then risk memory, or at least to minimize, memory corruption.

                      I would recommend using Buffer.BlockCop y to copy arrays (as you initially
                      asked).

                      Alternatively I would use Marshal.Copy, Marshal.PtrToSt ructure,
                      Marshal.Structu reToPtr and possible other methods on the
                      System.Runtime. InteropServices .Marshal class to marshal from the Managed to
                      Unmanaged world.

                      I would not attempt to implement my own marshaller with CopyMemory as the
                      ..NET Framework team has already done the work for me...

                      --
                      Hope this helps
                      Jay
                      T.S. Bradley - http://www.tsbradley.net


                      "Dennis" <Dennis@discuss ions.microsoft. com> wrote in message
                      news:56EB7C46-010F-4B0C-A70E-55F9BB89321F@mi crosoft.com...
                      |I am trying to use CopyMemory to copy arrays as follows:
                      |
                      | Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMem ory" (ByVal
                      | pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)
                      |
                      | dim kin(11) as Integer
                      | dim kout(11) as Integer
                      |
                      | kin(1)= 1 'set values for two elements to see if Kout is the same
                      | kin(5) = 5
                      |
                      | CopyMemory(kout (0), kin(0), 48)
                      |
                      | It compiles and runs but all I get in Kout is "0" for all elements.
                      |
                      | --
                      | Dennis in Houston


                      Comment

                      Working...