Win32::API cannot load any DLL?

C

cyl

When I used Win32::API to load my dll, perl.exe got exception. I did
some search in the archive and there's one article mentioning that the
export functions must use stdcall naming convention for Win32::API to
use. Is it true? This means that Win32::API can not support any kind
of dlls, right? Is there any fix to that? Thanks.
 
S

Sisyphus

cyl said:
When I used Win32::API to load my dll, perl.exe got exception. I did
some search in the archive and there's one article mentioning that the
export functions must use stdcall naming convention for Win32::API to
use. Is it true? This means that Win32::API can not support any kind
of dlls, right? Is there any fix to that? Thanks.

There's a patched version that claims to also handle functions declared with
'cdecl' at http://www.xs4all.nl/~itsme/projects/perl/ . (There's a link to a
ppm for it on that page.)


Other than that you can use XS or Inline::C to access the dll. (There's a
nice little example of accessing user32.dll from Inline::C near the end of
'perldoc Inline::C-Cookbook'.)

Cheers,
Rob
 
C

cyl

some search in the archive and there's one article mentioning that the
I try to build a dll myself using VS2005 and VC6 and got the following
results

stdcall cdecl
VC6 Win32::API new failed Win32::API new failed
VS2005 Win32::API new failed perl.exe got exception

None of them works. So far only Windows dlls such as Kernel32.dll
work. Do I have anything wrong?
 
B

Bart Lateur

cyl said:
When I used Win32::API to load my dll, perl.exe got exception. I did
some search in the archive and there's one article mentioning that the
export functions must use stdcall naming convention for Win32::API to
use. Is it true? This means that Win32::API can not support any kind
of dlls, right? Is there any fix to that? Thanks.

No, in theory, if you build your DLL right, you can call it. I've done
it in the past, so I know it works, but I'm not a C guru so I'm not the
person to tell you exactly what you're doing wrong.
 
S

Sisyphus

cyl said:
I try to build a dll myself using VS2005 and VC6 and got the following
results

stdcall cdecl
VC6 Win32::API new failed Win32::API new failed
VS2005 Win32::API new failed perl.exe got exception

None of them works. So far only Windows dlls such as Kernel32.dll
work. Do I have anything wrong?

Perhaps you omitted the '.def' file ?

You should get good milage with VC 6 ... not so sure about VS2005.

The files that follow have been transcribed from another machine - beware of
typos.

-- msdll.c --
int dll_int_square (int i)
{
return i * i;
}
-- end of msdll.c --

-- msdll.def --
EXPORTS
dll_int_square
-- end of msdll.def --

Then build msdll.dll with the following command:

cl /LD /Gz msdll.c msdll.def

(The Gz switch enforces the stdcall calling convention.)

-- msdll.pl --
use Win32::API;
use warnings;

$function = Win32::API->new('msdll.dll', 'int dll_int_square(int i)',);
$return = $function->Call(12);
print $return, "\n";
-- end of msdll.pl --

For me, running 'perl msdll.dll' prints out 144 (as expected).

Cheers,
Rob
 
C

cyl

For me, running 'perl msdll.dll' prints out 144 (as expected).

It does not work me. I can compile the dll correctly but Win32::API
just failed to load it. I've decided to try SWIG as my solution. Many
thanks for the help. IMO, there should be room for the implementation
of this dll loading stuff because I can use other script language such
as Ruby to load my dll without any problem. Just wondering if there's
any difficulty for Perl to support such capability (loading cdecl
declared function)?
 
S

Sisyphus

It does not work me. I can compile the dll correctly but Win32::API
just failed to load it. I've decided to try SWIG as my solution. Many
thanks for the help. IMO, there should be room for the implementation
of this dll loading stuff because I can use other script language such
as Ruby to load my dll without any problem. Just wondering if there's
any difficulty for Perl to support such capability (loading cdecl
declared function)?

I hope you tried to run the script as 'perl msdll.pl' not 'perl msdll.dll'
(as I wrote :)

I don't know why you're having trouble with the formulation I provided - it
should work fine.
Is the dll in the the path ? (I think it needs to be - unless you provide
the fully qualified name.)

Did you build the dll using VC 6 ? (Safest to use the compiler that was used
to build perl - which is VC 6 , if you're using ActiveState perl.) I find
that I get failures, too, if I try to mix compilers (VC 6 and VC 7 in my
case).

Do you get any warnings or error messages with any of the failures ?

Perl has absolutely no difficulty with loading dll's (irrespective of the
calling convention used) - it's only the CPAN version of Win32::API that has
trouble with cdecl.

As an alternative to accessing the demo dll (that I provided with my last
post) using Win32::API, it's quite trivial to access that dll function
using Inline::C:

--inline.pl--
use warnings;
use Inline C => Config =>
BUILD_NOISY => 1,
LIBS => '-LC:/path/to/import_lib -lmsdll'; # link to the import lib
(msdll.lib)

use Inline C => <<'EOC';

int wrap_dll(int x) {
return dll_int_square(c);
}

EOC

my $num = 12;
print wrap_dll($num);

-- end Inline.pl --

That will work just as well, even if the dll was not built using stdcall.
(Again, you may strike trouble if you mix compilers.)

Or you can achieve the same using XS directly.

Or you can use swig :)

Cheers,
Rob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top