EricDB has asked for the wisdom of the Perl Monks concerning the following question:

I have created a very simple DLL that exports a function called inc_number(), whose function is to increment a number. I imported it into Perl and invoked it like so:

use Win32::API; die "ack!" unless Win32::API->Import('testdll.dll', 'int inc_number(in +t *num)'); my $num = 5; inc_number($num); print "Number is now $num\n";


Instead of the "Number is now 6" that I was hoping for, I got:

The instruction at 0xblahblah referenced memory at 0x00000005. The memory could not be "written".

If I change the initial value of $num to 8, then the memory address in the illegal operation changes to 0x00000008 as well.

It seems like maybe Perl isn't properly recognizing that this is a by-ref parameter, and is passing by value instead?

UPDATE

I tried using the deprecated method of importing a function where you specify the parameter types instead of giving it the C prototype. It worked! Almost. 7 becomes 8, 8 becomes 9, and 9 becomes colon. 900 becomes :00. It seems like it's just incrementing the ASCII value of the first character in the numeric representation of my value. Hmm.

Replies are listed 'Best First'.
Re: Win32::API - Passing "by reference"
by Corion (Patriarch) on Nov 25, 2003 at 07:25 UTC

    I didn't delve deep into the Win32::API internals, but I had previously success by using the other, packed style of parameter declaration:

    use Win32::API; my $inc_number = Win32::API->new('testdll.dll','inc_number',"P","I"); sub inc_number { $inc_number->(@_); };

    The P passing style passes a pointer to the value of the variable, but I'm not sure whether the variable will be magically converted to an int or be passed as string, so you maybe have to pack the value to a 4 byte string with the first byte being 0x08.

    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
Re: Win32::API - Passing "by reference"
by Art_XIV (Hermit) on Nov 25, 2003 at 13:54 UTC

    This is just a SWAG - but did you register your .dll?

    Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"

      It ain't a COM/OLE dll. You can't register plain old ordinary DLLs.

      Jenda
      Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
         -- Rick Osborne

      Edit by castaway: Closed small tag in signature