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


in reply to Re: Calling a function form an external DLL with Inline::C on windows
in thread Calling a function form an external DLL with Inline::C on windows

As for the Win32::API method, I think it finds both the dll and the function in it. If it failed at either task, it would croak something like "Undefined sub &main::RegisterClient2 in..." - which it did, when I misspelled the path. I'll try to check $^E tomorrow, but the fact that the whole program crashed when I used the $function = Win32::API->new(), $function->Call() syntax doesn't fill me with too much hope.

As for the Inline method: no, no .lib, only the .dll. I've found some advice on the net that said MinGW is able to use the dll directly. However, there might be a path problem related to MinGW's setup (or whatever) here that I can't figure out.

I don't have dumpbin.exe, at least I'm not aware of it. (Can't tell now, as I'm writing from a different machine)

Replies are listed 'Best First'.
Re^3: Calling a function form an external DLL with Inline::C on windows
by BrowserUk (Patriarch) on Aug 06, 2010 at 01:19 UTC

    Given this C:

    #include <stdio.h> __declspec(dllexport) int RegisterClient2(int *pnClientId, const char *pszIPAddress) { printf( "id:%d addr: %s\n", *pnClientId, pszIPAddress ); return 12345; }

    Compiled to a DLL like this:

    C:\test>cl /LD /MT 853196dll.c Microsoft (R) C/C++ Optimizing Compiler Version 15.00.21022.08 for x64 Copyright (C) Microsoft Corporation. All rights reserved. 853196dll.c Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:853196dll.dll /dll /implib:853196dll.lib 853196dll.obj Creating library 853196dll.lib and object 853196dll.exp

    And this Inline::C:

    #! perl -slw use strict; use Inline C => Config => BUILD_NOISY => 1, LIBS => 'c:\test\853196dll +.lib'; use Inline C => <<'END_C', NAME => '_853198_IC', CLEAN_AFTER_BUILD => + 0; int RegClient( SV *id, SV *IP ) { int c_id = SvIV( id ); char *c_ip = SvPVX( IP ); return RegisterClient2( &c_id, c_ip ); } END_C print RegClient( 123, 'fred' );

    Running the Perl code gives:

    C:\test>853196-ic.pl Starting Build Preprocess Stage Finished Build Preprocess Stage Starting Build Parse Stage Finished Build Parse Stage Starting Build Glue 1 Stage Finished Build Glue 1 Stage Starting Build Glue 2 Stage Finished Build Glue 2 Stage Starting Build Glue 3 Stage Finished Build Glue 3 Stage Starting Build Compile Stage Starting "perl Makefile.PL" Stage Writing Makefile for _853198_IC Finished "perl Makefile.PL" Stage Starting "make" Stage Microsoft (R) Program Maintenance Utility Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. C:\Perl64\bin\perl.exe C:\Perl64\lib\ExtUtils\xsubpp -typem cl -c -IC:/test -nologo -GF -W3 -MD -Zi -DNDEBUG -Ox -GL _853198_IC.c _853198_IC.xs(7) : warning C4244: 'initializing' : conversion from ' _853198_IC.xs(9) : warning C4013: 'RegisterClient2' undefined; assum Running Mkbootstrap for _853198_IC () C:\Perl64\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 C:\Perl64\bin\perl.exe -MExtUtils::Mksymlists -e "Mksymlists link -out:blib\arch\auto\_853198_IC\_853198_IC.dll -dll -nolo 2.lib" "C:\Program Files\Microsoft SDKs\Windows\v6.1\Lib\X64\winspool rosoft SDKs\Windows\v6.1\Lib\X64\uuid.lib" "C:\Program Files\Microsof \Microsoft Visual Studio 9.0\VC\Lib\amd64\msvcrt.lib" -def:_853198_IC Creating library blib\arch\auto\_853198_IC\_853198_IC.lib and obje Generating code Finished generating code if exist blib\arch\auto\_853198_IC\_853198_IC.dll.manifest mt if exist blib\arch\auto\_853198_IC\_853198_IC.dll.manifest de C:\Perl64\bin\perl.exe -MExtUtils::Command -e "chmod" -- 755 C:\Perl64\bin\perl.exe -MExtUtils::Command -e "cp" -- _85319 C:\Perl64\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 Finished "make" Stage Starting "make install" Stage Microsoft (R) Program Maintenance Utility Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. Files found in blib\arch: installing files in blib\lib into architectu +re Installing C:\test\_Inline\lib\auto\_853198_IC\_853198_IC.dll Installing C:\test\_Inline\lib\auto\_853198_IC\_853198_IC.exp Installing C:\test\_Inline\lib\auto\_853198_IC\_853198_IC.lib Installing C:\test\_Inline\lib\auto\_853198_IC\_853198_IC.pdb Finished "make install" Stage Starting Cleaning Up Stage Finished Cleaning Up Stage Finished Build Compile Stage id:123 addr: fred 12345

    Whether you can adapt that to work with MinGW, and no .lib I don't know.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      AHA! Thanks!

      If I define a wrapper function around the existing library function and call that (the wrapper) from perl, it seems to work.

      According to Inline::C's documentation there is an AUTOWRAP mode, which would alleviate the need for those wrapper functions, but I couldn't make it work so far.

        I had a couple of goes at the AUTOWRAP, and I couldn't work out the magic incantations to make it work either.

        With regard to Win32::API.

        Which versions that module and Perl are you using?

        Is the Perl home built? If so with which compiler?

Re^3: Calling a function form an external DLL with Inline::C on windows
by BrowserUk (Patriarch) on Aug 05, 2010 at 23:17 UTC

    Do you at least know what calling convention the DLL was built with?