Announcement

Collapse
No announcement yet.

Help with VirtualAlloc()

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help with VirtualAlloc()

    Hi. Im calling the VirtualAlloc() function and according to material i've read about this function, passing it a 0 for the address is supposed to allow windows to pick an address. However, this never works. The only way i can successfully reserve a region is to explicitly pass in an address. Any ideas what i'm doing wrong?

    Code:
    #COMPILE EXE
    #DIM ALL
    #REGISTER NONE
    
    #INCLUDE "win32api.inc"
    
    %PAGE_SIZE = 4096   'on Alphas, the page size is 8196 PB code wont run on Alpha cpu's will it?
    
    %PAGE_NOACCESS =         &H01
    %PAGE_READONLY =         &H02
    %PAGE_READWRITE =        &H04
    %PAGE_WRITECOPY =        &H08
    %PAGE_EXECUTE =          &H10
    %PAGE_EXECUTE_READ =     &H20
    %PAGE_EXECUTE_READWRITE =&H40
    %PAGE_EXECUTE_WRITECOPY = &H80
    %PAGE_GUARD =           &H100
    %PAGE_NOCACHE =         &H200
    %PAGE_WRITECOMBINE =    &H400
    %MEM_COMMIT =          &H1000
    %MEM_RESERVE =         &H2000
    %MEM_DECOMMIT =        &H4000
    %MEM_RELEASE =         &H8000
    %MEM_FREE =           &H10000
    %MEM_PRIVATE =        &H20000
    %MEM_MAPPED =         &H40000
    %MEM_RESET =          &H80000
    %MEM_TOP_DOWN =      &H100000
    %MEM_4MB_PAGES =   &H80000000
    %SEC_FILE =          &H800000
    %SEC_IMAGE =        &H1000000
    %SEC_VLM =          &H2000000
    %SEC_RESERVE =      &H4000000
    %SEC_COMMIT =       &H8000000
    %SEC_NOCACHE =     &H10000000
    %MEM_IMAGE =        &H1000000  'SEC_IMAGE
    
    FUNCTION PBMAIN()
       DIM lpAddress AS LONG
       DIM lRet AS LONG
    
       lpAddress = %NULL       ' passing NULL is supposed to let windows pick an address
        
       lRet = VirtualAlloc(lpAddress, %PAGE_SIZE, %MEM_RESERVE, %PAGE_READWRITE)
       MSGBOX STR$(lpAddress)  ' always returns 0  Why?
       
       lpAddress = &00400000
       lRet = VirtualAlloc(lpAddress, %PAGE_SIZE, %MEM_RESERVE, %PAGE_READWRITE)
       MSGBOX STR$(lpAddress)  ' this returns a valid address
       
       lRet = VirtualFree (lpAddress, 0, %MEM_RELEASE)
    END FUNCTION

    Any help would be appreciated.
    Thanks
    -Mike

    ------------------

  • #2
    Mike..

    Actually, neither is working...

    Pass the function BYVAL %NULL and check the return address NOT the
    value of lpAddress as you are doing. If you pass BYVAL %NULL you will
    get a correct Address returned. Setting lpAddress = &00400000 actually
    returns Zero.


    ------------------
    Jim..
    [email protected]
    Jim..

    Comment


    • #3
      Thanks Jim! That did the trick.

      By the way, the declare in the win32api.inc is:

      DECLARE FUNCTION VirtualAlloc LIB "KERNEL32.DLL" ALIAS "VirtualAlloc" (lpAddress AS ANY, BYVAL dwSize AS LONG, BYVAL flAllocationType AS LONG, BYVAL flProtect AS LONG) AS LONG

      Im not terribly keen on proper API declares, but should the (lpAddress as ANY) be ByVal lpAddress as Long? I assumed it was supposed to be passed ByRef and that the value would be updated with an address.

      -Mike

      ------------------




      [This message has been edited by Mike Joseph (edited August 26, 2000).]

      Comment


      • #4
        Mike..

        In order to add to confusion..

        lpAddress is defined as LPVOID (i.e. Pointer to any type) in VirtualAlloc
        This is a long pointer to ANY type. You really need to check with
        someone with greater knowledge but personally, I would define it as
        lpAddress as LONG since under almost any scenario that I can think
        of it would be a long. Defined AS ANY, as it currently is, passes the
        32-bit address just as BYREF would. My belief is that it is subjective
        to use BYVAL in this case but I would add that I think that in most
        cases that I can think of you would use BYVAL. It would depend on
        where the memory address came from and how it was stored. By storing
        in a variable you would most likely want to pass BYVAL since you
        would not want to pass the address of the variable but the value
        being held in the variable which would be the address. An example
        of this would be your original code. You set lpAddress to %NULL.
        If you will test this, you will see that passing BYVAL lpAddress
        will give you success but passing BYREF will not since you would be
        passing the address of lpAddress. Other circumstances could be
        different.

        As far as assuming that the function would stuff a memory address
        in lpAddress. By definition it states the "return value" will be
        the base address of the allocated region of pages if successful.
        My assumption is that your assumption, in this case, was just
        like most of my assumptions.. Incorrect

        I'm certain our Kiwi friend (i.e. Lance) or others could/would
        shed a much better and more accurate light on this subject for you.


        ------------------
        Jim..
        [email protected]
        Jim..

        Comment


        • #5
          Jim,

          I would add just one more thing. VirtualAlloc() is a 'C' function,
          and in contrast to basic functions which pass arguments by reference
          as default, 'C' passes them by value.

          Therefore, you must use BYVAL %NULL, since the 'C' function expects
          it by value. Otherwise, you will be passing it's address, contrary
          to what 'C' expects.

          At least that's the way I've rationalized this tricky stuff.

          ------------------

          Comment

          Working...
          X