in reply to How to use Win32::API to access variable in DLL file?

You don't need Win32::API nor compiler, to access those values. It can all be done using Win32 that comes with AS Perl's.

Given a dll that contains this exported integer (compiled as test.dll):

__declspec(dllexport) int testint = 12345;

That might be accessed from a C program so:

#include <windows.h> #include <stdio.h> int main( int argc, char **argv ) { HMODULE hm = (HMODULE)LoadLibrary( "test.dll" ); int *ptestint = (int *)GetProcAddress( hm, "testint" ); printf( "Addr: %x Value: %d\n", ptestint, *ptestint ); return 1; }

It can be accessed from (AS) perl as follows:

#! perl -slw use strict; use Win32; my $dll = Win32::LoadLibrary( 'test' ) or die $^E; my $proc = Win32::GetProcAddress( $dll, 'testint' ) or die $^E; print unpack 'V', unpack 'P4', pack 'L!', $proc; __END__ C:\test>\perl32\bin\perl.exe 773754.pl 12345

The complicated bit is the last line:

  1. pack 'L!', $proc converts the UV returned by GetProcAddress() back into a binary value;
  2. unpack 'P4', ... fetches 4-bytes (the exported integer) from that address;
  3. unpack 'V', ... converts those 4-bytes into a perl scalar;

Assuming that your running on a platform where int and long and synonymous, that should work for all three values. Otherwise you'll need to adjust the 'V' for the last one.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP PCW

Replies are listed 'Best First'.
Re^2: How to use Win32::API to access variable in DLL file?
by dasgar (Priest) on Jun 23, 2009 at 19:12 UTC
    Cool! Thanks! That's exactly what I was looking for: a simple pure Perl solution. Plus, it looks like you saved me a trip through time. :)

    From ActiveState's documention on Win32::GetProcAddress :
    Returns the address of a function inside a loaded library. The information about what you can do with this address has been lost in the mist of time. Use the Win32::API module instead of this deprecated function.

    Now there's one concern in my mind. If I use Win32 to access the variables and Win32::API to access the functions, would the two modules load different instances of the dll? If so, I'll have another problem on my hands.

    If I understand correctly, I suspect that I can follow your example and by using only the pack 'L!', $proc syntax of the last line to get the address of variables and functions. With that, I should be able to get any variable or function in my code to 'point' to a corresponding variable/function in the dll and would not necessarily need Win32::API. Then I don't have to worry about the possibility of my code accessing different instances of the dll.

    If I get this all figured out, I'll be sure to post an update on what I did so that others can learn from my travels guided by your useful information.

    Again, thanks for the help!
      If I use Win32 to access the variables and Win32::API to access the functions, would the two modules load different instances of the dll?

      No. If the dll in question is already loaded, then LoadLibrary() just returns a handle to it.

      If I understand correctly, I suspect that I can follow your example and by using only the pack 'L!', $proc syntax of the last line to get the address of variables and functions. With that, I should be able to get any variable or function in my code to 'point' to a corresponding variable/function in the dll and would not necessarily need Win32::API. Then I don't have to worry about the possibility of my code accessing different instances of the dll.

      Like I say, not a possibility. Besides which, whilst you can get the procedure addresses in the same way, the Pure Perl technique for invoking that address is still lost in the mists of time. On top of that, how would you set up the parameter passing?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        You were correct about using the modules will not create seperate instances of the dll. I was able to successfully use the driver dll to access the device and to access the dll's global variable to determine if errors occurred.

        Thanks for the information and help. I really appreciate it.