Module Win32::API and DLL with Windows Visual C++

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
I am having trouble getting my own DLLs to work with the above module
(ver 0.55).
I can get the examples to work from the write up that involve the DLLs
from kernal32,
but not from my own little DLL project file.

I fear I need a simple example DLL project for MS Visual C++ 6 that
does work.
Can anyone help here?

The current fault I have is;
"Can't call method "Call" on an undefined value at
line 44."

With the following lines of PERL code:
   use Win32::API;
   $function = Win32::API->new(
'int ANSIchar(int a, int b)'
   $return = $function->Call( 1, 2 ) ;     # This is line 44

I have change this around but $function is always undefined.
I am not sure if Win32::API is the appropriate tool for accessing user
DLLs. ??

Regards JC....

Re: Module Win32::API and DLL with Windows Visual C++

Quoted text here. Click to load it

You haven't included the C code, so I can't see if you've done this
already, but I believe functions need to be marked __stdcall for
Win32::API to be able to call them. The default calling convention
(__cdecl) won't work.

...checking the documentation, this appears to no longer be true as of
version 0.48. You now *can* load __cdecl functions, but you have to
explicitly mark them as such when you import them.

Quoted text here. Click to load it

If you had checked the return value of ->new and printed and appropriate
error message you would have a better idea why things are failing.

    my $function = Win32::API->new(...)
        or die "can't import ANSIchar from test.dll: $^E";

(Notice I added a 'my' there. You need to add 'use strict;' to the top
of your program and fix all the resulting errors.)

Quoted text here. Click to load it

Well, there are several alternatives. The most long-winded and most
likely to work successfully is to write a proper XS module that wraps
the DLL. If you find XS too complicated, you could use Inline::C to do
the grunt-work for you, though IME it brings its own list of
complications I prefer to do without. You could also try P5NCI, but I
don't know how well it works.


Re: Module Win32::API and DLL with Windows Visual C++

Quoted text here. Click to load it

For mine, Win32::API is *not* the ideal way to access user DLLs
1) you don't have a C compiler
2) your C compiler cannot link to DLLs directly (ie needs to link to
an import lib) and you don't have an import library for that DLL.

With Strawberry Perl, neither 1) nor 2) will be the case (as
Strawberry Perl comes with the MinGW port of the gcc compiler - which
is a C compiler that can link directly to a DLL if need be).
With ActiveState Perl neither 1) nor 2) will be the case if you first
'ppm install MinGW'.

Ben's advice is, as always, sound. But don't let his recommendations
deter you from using Inline::C which is a powerful and flexible tool
that allows you to take the XS solution without having to learn how to
write an XS file. (You may need to become familiar with the perl API,
however - 'perldoc perlapi'.)

And feel free to use Inline::C with windows system DLLs too:

use Inline C => DATA =>
MYEXTLIB => 'C:/windows/system32/user32.dll';

$text = "@ARGV" || ' works with MSWin32. Scary...';

WinBox('Inline Text Box', $text);


int WinBox(char* Caption, char* Text) {
    return MessageBoxA(0, Text, Caption, 0);

That's based on an example in the Inline::C-Cookbook documentation -
it links directly to user32.dll. To use that script with a Microsoft
Compiler you'd have to replace:

MYEXTLIB => 'C:/windows/system32/user32.dll';
LIBS => '-luser32';

With MinGW, both of those 2 variations work (assuming user32.dll is in
C:/windows/system32, of course).

Once your Inline::C solution has been written you can always convert
to XS (and avoid the dependency upon Inline) using
<plug>InlineX::C2XS</plug>, again without having to go to the trouble
of writing the XS file yourself.


Site Timeline