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

I have a COM object that exposes the following method:
GetErrorStr(DWORD errCode, VARIANT* errStr)
The IDL is as follows: [id(8), helpstring("method GetErrorStr")] HRESULT GetErrorStr([in] DWORD errCode, [out] VARIANT* errStr); The method accepts a DWORD parameter, looks up an error text string and returns it via errStr. I can call the method via IDispatch from VBScript w/o problem. But when calling this method from perl, the errStr is not returned to the perl program. My perl code follows:

use strict; use Win32::OLE; use Win32::OLE::Variant; my $obj = Win32::OLE->new('PDH.PDHQuery'); print("Failed to create connection to PDHQUERY object\n") if (not +$obj); my $errstr = Variant(VT_BSTR|VT_BYREF, Variant(VT_EMPTY)); $obj->GetErrorStr( Variant(VT_I4|VT_BYREF, 12345), $errstr );
many thanks

20031126 Edit by Corion: Fixed formatting

Replies are listed 'Best First'.
Re: in/out Win32:Ole strings
by Roger (Parson) on Nov 27, 2003 at 01:12 UTC
    I highly suspect that the problem is with your
    $obj->GetErrorStr(Variant(VT_I4|VT_BYREF,12345),$errstr);
    line, where you had VT_BYREF flag set. This would effectively pass the address of '12345' instead of the value of '12345' into the COM method. By definition your COM method requires an error code passed by value, not by reference.

    I suspect that if you change the code to
    $obj->GetErrorStr(Variant(VT_I4,12345),$errstr);
    then it would work.

Re: in/out Win32:Ole strings
by NetWallah (Canon) on Nov 27, 2003 at 05:59 UTC
    If I remember my "c" correctly, the second parameter required by GetErrorStr is a POINTER to a pre-allocated null-terminated string.

    You may have better luck trying the following:

    $obj->GetErrorStr( Variant(VT_I4|VT_BYREF, 12345), \$errstr ); #Notice REFERENCE to $errstr