manojghosh has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

I have following function in win32 DLL

BSTR _stdcall dec(unsigned long isize,long* iReturn);

I want to call this function in Perl script. I have tried different options in Perl but stuck on this. Please help me out and provide your valuable solutions. I have tried the following code but did not get success:

#!/usr/bin/perl use Win32::API; my $xy=0; my $cc=\$xy; Win32::API->Import('MyDLL', 'char* dec(long a,long* b)')or die $^E; my $var=dec(4,$cc); printf("%s",$var);

So how to get the return string using char*

Thanks in Advance, :-)

Replies are listed 'Best First'.
Re: Perl Win32::API and BSTR
by ikegami (Patriarch) on Mar 01, 2011 at 08:28 UTC

    Your question makes no sense. It doesn't return a char*, so you can't use char*. If you tell it it's a char*, Win32::API will treat it as a null-terminated string. Win32::API doesn't know anything about BSTR, so you'll have to tell Win32::API that the pointer is a number, fetch the BSTR yourself, and extract the string therein yourself.

    use Encode qw( decode ); use Win32::API qw( ); sub bstr_to_str { my ($bstr) = @_; my $len = unpack('V', unpack('P4', pack('J', $bstr-4))); my $raw = unpack("P$len", pack('J', $bstr)); return decode('UTF-16le', $raw); } my $SysFreeString = Win32::API->new('oleaut32.dll', 'SysFreeString', ' +N', 'V') or die $^E; sub SysFreeString { my ($bstr) = @_; $SysFreeString->Call($bstr); } my $dec = Win32::API->new('mydll', 'dec', 'IP', 'N') or die $^E; sub dec { my $iSize = $_[0]; our $iReturn; local *iReturn = \$_[1]; #my $iReturn_buf = pack('l', $iReturn); # If in-out my $iReturn_buf = pack('l', 0); # If out my $rv_bstr = $dec->Call($iSize, $iReturn_buf); $iReturn = unpack('l', $iReturn_buf); my $rv = bstr_to_str($rv_bstr); SysFreeString($rv_bstr); return $rv; }

    Untested.

    Notes:

    • You didn't specify if iReturn is an input and an output, or just an output. I assumed the latter, but provided the code for the former in a comment.
    • I kept the C calling convention (2nd argument is modified) since I didn't know enough about the function to make it more Perlish.
    • I assumed the returned BSTR needs to be freed, and that this should be done using SysFreeString.

    Update: Oddly, the pointer doesn't point to the start of the structure but to the start of the character data (for compatibility with WCHAR*). Fixed.

      Gee, Thanks!™   That is very useful information about BSTRs.   I was “stumbling around” for just this information, just the other day.   Did I merely overlook it, or does this reply need to be copied into another section where it can be easily found?   (Tutorials?)

        ok..? Any info you might glean about BSTR from my post is more clearly presented in the first match for "BSTR" on Google.

        I would think the interesting parts of my post are:

        • How to handle output and input-output parameters with Win32::API.
        • How to handle pointers to structures with Win32::API.
Re: Perl Win32::API
by Anonymous Monk on Mar 01, 2011 at 07:50 UTC
    substr $cc, 0, $var; like the docs show