how to define a SAFEARRAY in perl

how to define a SAFEARRAY in perl

am 03.06.2005 06:40:41 von scott

Hello All

we are trying to call (COM method via IIS and SOAP)

STDMETHODIMP CSoapReciever::PutDetails(SAFEARRAY **int_args, SAFEARRAY
**string_args)

from perl via soap


we are trying to define and load the SAFEARRAY's in perl as follows.

sub soapPutClientDetails {
# Setup SOAP:
my $soap = SOAP::Lite
-> service($serviceUrl);

my $IntArray;
my $StrArray;

$IntArray->[0] = 826;
$IntArray->[1] = 3;

$StrArray->[0] = 'string';
$StrArray->[1] = 'string2';
$StrArray->[2] = 'string3';
$StrArray->[3] = 'string4';
$StrArray->[4] = 'string5';

# call PutClientDetails. We use $cgi->param (not $R) to ensure
only use first value of any multi value entries
my $regClientRes = $soap->PutDetails ($IntArray, $StrArray);
}

This results in errors, we have no trouble returning a SAFEARRAY and
parsing the values but have trouble passing one in. The method above
simply reverses the method we use to parse the returned SAFEARRAY.

I can call this COM method successfully in C++ and I am logging
arguments to file. But it seems I never actually get into the function
body via soap. This leads me to believe there is some error in the
array declaration in perl or soap type conversion of the arguments
(SAFEARRAY).

Can anyone see where I am going wrong ?

Thanks

Re: how to define a SAFEARRAY in perl

am 04.06.2005 08:00:48 von tlviewer

"Scott" wrote in message
news:umnv91l3ph79ijei627aepkv0leu72v5kn@4ax.com...
>
> we are trying to define and load the SAFEARRAY's in perl as follows.
>
> sub soapPutClientDetails {
> # Setup SOAP:
> my $soap = SOAP::Lite
> -> service($serviceUrl);
>
> my $IntArray;
> my $StrArray;
>
> $IntArray->[0] = 826;
> $IntArray->[1] = 3;
>
> $StrArray->[0] = 'string';
> $StrArray->[1] = 'string2';
> $StrArray->[2] = 'string3';
> $StrArray->[3] = 'string4';
> $StrArray->[4] = 'string5';
>
> # call PutClientDetails. We use $cgi->param (not $R) to ensure
> only use first value of any multi value entries
> my $regClientRes = $soap->PutDetails ($IntArray, $StrArray);
> }

Here's a sample WMI script that allocates for Variant arrays, aka SAFEARRAY.
Notice the calls to
Variant()
Check out the Win32::OLE docs for more details.

regards,
tlviewer


#!/usr/bin/perl -w
use Win32::OLE::Variant qw(:DEFAULT nothing);

my $HKLM = 0x80000002;
(my $machine = shift @ARGV || "." ) =~ s/^[\\\/]+//;

my $locator = Win32::OLE->new('WbemScripting.SWbemLocator')
or die "Cannot access WMI on local machine: ", Win32::OLE->LastError;

my $WMIServices = $locator->ConnectServer('.', "root\\default")
or die "Cannot access WMI on remote machine: ", Win32::OLE->LastError;

my ($objRegistry, $sValue, $sKey);
$objRegistry= $WMIServices->Get("StdRegProv") or
die "Cannot create Registry Object :", Win32::OLE->LastError;

# init as integer
my $iRC = 0;

# allocate space for Variant BSTR
my $sout = Variant(VT_BSTR | VT_BYREF, "");

my $sPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion";

# yours is not to do or Die (for once, haha )
$iRC= $objRegistry->GetStringValue($HKLM, $sPath,
"ProductId", $sout ); # or die( "failed \n" , Win32::OLE->LastError);
print $sout, " \n";

# allocate for variant_array_of_variants (vartype 8204)
my $arr = Variant( VT_ARRAY | VT_VARIANT | VT_BYREF , [1,1] );

$sPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";

# Do not use Die for this method
$iRC = $objRegistry->EnumKey($HKLM, $sPath, $arr); # or die "Cannot fetch
registry key :", Win32::OLE->LastError;

foreach my $item ( in( $arr->Value ) )
{
print "$item \n";
} # end foreach

__END__