http://www.perlmonks.org?node_id=1024303

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.

    from http://search.cpan.org/~bulkdd/Win32-API-0.75/API.pm#CALLING_AN_IMPORTED_FUNCTION.
    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