Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Win32::api v0.75 issue importing DLL

by FabPerlExplorer (Initiate)
on Mar 19, 2013 at 13:52 UTC ( #1024303=perlquestion: print w/replies, xml ) Need Help??
FabPerlExplorer has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm actually importing a dll within a perl script using Wi32::api module. The dll is very simple:
extern "C" { __declspec(dllexport) int dummyFunc(); __declspec(dllexport) int dummyFunc2(int a ); }
Using both function within a perl with Win32::api v0.65 works properly. Doing the same with Win32::api v0.75 lead to a Perl crash calling the  int dummyFunc2(int a ) function. No crash calling a function without any input parameter. The crash happens just after the function return (every action inside the function is done). If I call a function within a standard windows DLL (like Kernel32.dll) it works without problem. Therefore the issue seems to be related to the Api version but also to the DLL. Any suggestion about what is going wrong? My setup is: - Windows7 - Active state perl v5.16 - DLL has been compiled with MSVc++ express and QtCreator (mingw) Thanks

Replies are listed 'Best First'.
Re: Win32::api v0.75 issue importing DLL
by bulk88 (Priest) on Mar 20, 2013 at 03:03 UTC
    6. And optionally you can specify the calling convention, this defaults to '__stdcall', alternatively you can specify '_cdecl' or '__cdecl' (API > v0.68) or (API > v0.70_02) 'WINAPI', 'NTAPI', 'CALLBACK' (__stdcall), 'WINAPIV' (__cdecl) . False is __stdcall. Vararg functions are always cdecl. MS DLLs are typically stdcall. Non-MS DLLs are typically cdecl.

    You didn't post any code, but I will assume what is happening from "No crash calling a function without any input parameter. ". Win32::API did less error checking against wrong C prototypes in the past. By chance, (actually depending on what version/build number of Visual C or Mingw/GCC the Win32::API XS DLL was compiled with_, certain severe prototype mistakes (wrong number of params or __stdcall vs __cdecl mistake) in the past worked silently (but the C function might have been passed uninitialized memory). Under the hood, a 32 bit function that takes NO parameters (it may or may not have a return value) meets the definition of being __stdcall and __cdecl at the same time, so that will "magically work". ActiveState uses Visual C 6 for all 32 bit XS modules available through AS PPM, if you compile it yourself with "MSVc++ express" (version number??), that is a different compiler. I think your 0.65 came from ActiveState, and your 0.75 was compiled with a 21st century Visual C. On 64 bit Windows, __stdcall and __cdecl in Win32::API have no effect, so you can mess those 2 up in 64 bit Perl, and it will "magically work". Of course 32 bit portable is then gone because it will crash.
      Hi, I will check your suggestion. in the while below the codes. I'm not using the XS for time and effort reason (I have no experience with it). Then if it is possible I would like to use the win32api. the module code is the following:
      package Prova; #use strict; use warnings; # Import Win32::API and require version 0.64 use Win32::API 0.73; use Exporter; BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw( &dummyFunc &dummyFunc2 ); } BEGIN { $funcImportResult = Win32::API->Import('LibreriaDiProva', 'int dum +myFunc()'); $funcImportResult = Win32::API->Import('LibreriaDiProva', 'int dum +myFunc2(int a )'); } END{ } 1;
      while the perl script function is the following:
      #use lib qw(C:\UserData\JAZZ_FLOWS\DocToolForReport); use Prova; # To include Lessicum Client Universal interface wrapper $ciao = Prova::dummyFunc2(45); print $ciao;
Re: Win32::api v0.75 issue importing DLL
by Anonymous Monk on Mar 19, 2013 at 15:25 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1024303]
Approved by Corion
[Lady_Aleena]: Why does grep(/.*$in.*/, @my_modules) work but grep { $_ =~ /.*$in.*/; $_ } @my_modules not work? What did I do wrong in the second?
[tobyink]: Why are you returning $_ n your grep block? You should return a boolean.
[tobyink]: *in your grep block
[tobyink]: You can use grep { $_ =~ /.*$in.*/; } @my_modules but why not stick to grep(/.*$in.*/, @my_modules)? (The latter is faster.)
[shmem]: Lady_Aleena, in the first example grep evaluates the result from grep and if true, returns $_. In the second, it always returns $_
[shmem]: ..the result from the pattern match
[Lady_Aleena]: tobyink, I did after I failed to get the BLOCK to work. I can't seem to get my brain around grep BLOCK, though I'm okay with grep EXPR.
[shmem]: so in the second example grep returns all true elements of the list passed

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2017-05-27 07:40 GMT
Find Nodes?
    Voting Booth?