Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Interfacing to a pre-built DLL

by Bloodnok (Vicar)
on Oct 14, 2007 at 17:47 UTC ( [id://644776]=perlmeditation: print w/replies, xml ) Need Help??

Hi all ,

I thought you might like to learn of the results of all the painstaking research, seemingly endless candle burning, much muttering and not a little luck, when trying to interface Perl to an external library on a Windoze system.

Picture this ... there's an urgent, project related (aren't they all) need to realise automated functionality of a proprietary tool available only by utilising the vendor supplied API (defined in terms of documentation - together with .DLL, .LIB and a C++ header (.H) files).

My language of choice for the problem was Perl (via the Strawberry perl distribution I'd been pointed in the direction of via a response to an earlier question to the Monastry) and examples were provided only in Delphi, VC++ and VB ... none of which I had the remotest interest in dirtying my hands with, let alone learning - if for no other reason than project schedules didn't allow the time.

The 1st step was to gen up on XS and see if success could be gained by extrapolation from the examples ... nope, couldn't quite get it to work - that would've been be far too easy ;-)

The next step was to try one the Inline (Inline::CPP) module by Brian Ingerson and Neil Watkiss - with a similarly exasperating lack of success.

The next step involved the consideration of the vendor application as an OLE server and use Jan Dubois' Win32::OLE - again, that would've been far too easy .. and not a little inelegant given the existence of a proprietary API.

Having given up on OLE, why not try Cosimo Streppones' Win32::API approach ... great heavens above, success !! .. but at a cost - in a lot of ways, it neither looked or felt right ... but it worked :-))

Having got something working and the team engaged on producing an appropriate wrapper module, the urge to investigate the reasons for the failure of the previously tried methods got too great and in, once again, we delved.

Just how close success had previously been was demonstrated all too clearly when, having invetsigated the contents of the LIB file with a binary editor (actually, 'twas Gvim), how about, instead of identifying the DLL as the library file, identify the LIB file instead - lo and behold, that now works !!.

Now we suffered from the agony of choice - do we abandon the efforts thus far using Win32::API and engineer a proper solution, or carry on and regret, for ever, the decision ? For an engineer, in the interests of professionalism, the next step was obvious - change tack and do it right !!

The conclusion is, I submit obvious ... if you have a DLL to which you require a Perl interface, your approach should depend on the combination of the additional files you have access to &/or the requirements of the end result e.g. production/ prototype code

If the LIB file is available and production code is required, then XS has to be the way forward. Otherwise use one of the Inline modules.

If the LIB file is not available then Aldo Calpinis' Win32::API module is the thing for you.

Either way, I would heartily recommend the Strawberry perl distribution for Windoze development - especially if you have a limited budget &/or you don't have access to a VC++ environment - if nothing else, it is possible to write readily understandable, hugely practical make(1) scripts c/w the noddy scripts required by M$ nmake.

The next problem we have to solve is - as the header file describes the API in it's entirety, and the API is split across multiple DLL (and associated LIB) files, it it possible to refer to multiple libraries in e.g. MYEXTLIB ?

We shall see ...

Thanx Rob, these hints both paid off ... the only problem now is that, since the development machine was rebooted, nothing works at all - doncha just luv Windoze (tongue firmly in cheek;-)

Where it was previously working, the perl executeable now throws its' toys out of the pram when it can't find one of the DLLs upon which the API DLL depends - even tho' they are on the 'PATH' and the directory is accessible to all.

Using filemon (a poor mans' equivalent to truss(1M) or trace(1M) on *NIX), I can see the perl executeable trying some of the paths in PATH and then for some reason best known to itself, tries the rest of the paths but inserts the current working directory - leading to attempts to locate the DLL on paths of the form (assuming cwd() to be D:\\Dir): C:\\Program Files\\App\\lib\\"D:\\Dir\\"app.dll

At last, a user level that best describes my experience ... or does it ?? :-))

Replies are listed 'Best First'.
Re: Interfacing to a pre-built DLL
by spurperl (Priest) on Oct 14, 2007 at 18:30 UTC
    I've been there and can definitely feel your pain.
Re: Interfacing to a pre-built DLL
by syphilis (Archbishop) on Oct 15, 2007 at 03:24 UTC
    how about, instead of identifying the DLL as the library file, identify the LIB file instead

    There's actually a nice little demo of accessing a Windows dll in 'perldoc Inline::C-Cookbook'. (Look for the section "Just Desserts".) And, yes, it links to user32.lib - though, admittedly, there's no explicit statement to tell you that.

    (is) it possible to refer to multiple libraries in e.g. MYEXTLIB ?

    You would just refer to the various .lib files in LIBS - and make sure that the dll's are in your path.

    Cheers,
    Rob
Re: Interfacing to a pre-built DLL
by salva (Canon) on Oct 15, 2007 at 08:33 UTC
    another possibility, for simple DLLs, is P5NCI
Re: Interfacing to a pre-built DLL
by Errto (Vicar) on Oct 15, 2007 at 15:01 UTC
    I guess I don't quite get it. What's so wrong with Win32::API? I mean, I definitely see an argument for developing a custom module as a wrapper around that rather than using Win32::API directly in application code, but why go to the trouble of XS or Inline just to call an external DLL when you don't need to?
      Hi ,

      Aldo himself suggests that, for heavy duty use (and here I assume he's referring to production code et al), XS should be used in preference to his own Win32::API module ...

      At last, a user level that best describes my experience :-))

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://644776]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-23 15:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found