How to get an OLE array of objects?

How to get an OLE array of objects?

am 18.08.2006 00:33:16 von kingskippus

I'm really scratching my head over this. I have an OLE object with a
method that takes an [out] parameter that is an array of other OLE
objects. What I'd like to do is to get that array of other OLE objects
and iterate through them, printing out a property from each one. I
don't know that much about OLE objects, can someone please help? I've
been Googling for a couple of hours and feel like I'm close, but I
can't find anything for that last little bit.

Here's what I need using semi-pseudocode that I know won't work right:

use Win32::OLE;
my $tree = Win32::OLE->new( 'Tree.Component' );
my @nodes = array();

# GetNodes is a method of TreeComponent that is defined like this:
# int GetNodes([out] TreeNode[])
# where TreeNode is another OLE object type

$tree->GetNodes(\@nodes); # This doesn't work...
for $node (@nodes) {
print $node{Name}."\n"; # Name is a property of TreeNode objects
}

Here's a piece of code that I found on another site that the author
claims to work, but not quite for what I need. This code gets a double
back:

my $arg4 = Variant( VT_R8 | VT_BYREF, 0.0);
my $service = Win32::OLE->new( '3rdPartyComponent.Service' );
$service->foo( 31, 4000, 28000, $arg4 );

....But I don't want doubles, I want an array of objects, and not being
familiar with OLE at all, I'm totally stumped.

I sure would appreciate any help anyone can give me on this!

Re: How to get an OLE array of objects?

am 18.08.2006 12:57:37 von Paul Lalli

kingskippus@gmail.com wrote:
> I'm really scratching my head over this. I have an OLE object with a
> method that takes an [out] parameter that is an array of other OLE
> objects. What I'd like to do is to get that array of other OLE objects
> and iterate through them, printing out a property from each one. I
> don't know that much about OLE objects, can someone please help? I've
> been Googling for a couple of hours and feel like I'm close, but I
> can't find anything for that last little bit.
>
> Here's what I need using semi-pseudocode that I know won't work right:
>
> use Win32::OLE;
> my $tree = Win32::OLE->new( 'Tree.Component' );
> my @nodes = array();

This is not Perl. Are you thinking of PHP, perhaps? To declare an
array, you simply say:
my @nodes;

>
> # GetNodes is a method of TreeComponent that is defined like this:
> # int GetNodes([out] TreeNode[])
> # where TreeNode is another OLE object type
>
> $tree->GetNodes(\@nodes); # This doesn't work...

What do you mean by "doesn't work"? Did that give you a syntax error?
Run-time error? Or are you just assuming that it "didn't work" based
on later code?

> for $node (@nodes) {
> print $node{Name}."\n"; # Name is a property of TreeNode objects

Are you using strict and warnings? If not, turn them on. Here, you're
trying to access a hash named %node, rather than a hashref named $node.
Assuming @nodes does contain an array of hashes (or objects), this
should be:
print $node->{Name} . "\n";

Paul Lalli

Re: How to get an OLE array of objects?

am 18.08.2006 19:49:20 von kingskippus

Hi Paul, thanks for the response!

> > use Win32::OLE;
> > my $tree = Win32::OLE->new( 'Tree.Component' );
> > my @nodes = array();
>
> This is not Perl. Are you thinking of PHP, perhaps? To declare an
> array, you simply say:
> my @nodes;

Yes, you're probably right. I'm definitely using Perl for this
project, but I'm working on another project in PHP at the same time.
(You should see how many times both intepreters have basically told me,
"You can't do that, stupid!") If you see something that is PHP-ish,
please imagine that it's actually in Perl. That last line should have
just been:

my @nodes;

> > $tree->GetNodes(\@nodes); # This doesn't work...
>
> What do you mean by "doesn't work"? Did that give you a syntax error?
> Run-time error? Or are you just assuming that it "didn't work" based
> on later code?

No, it doesn't give any kind of error, but if I issue a print @nodes; I
get zero (no elements) even though I've verified in another utility
that the function, when called correctly, does indeed return results.
(Around 89 nodes, actually.)

> > for $node (@nodes) {
> > print $node{Name}."\n"; # Name is a property of TreeNode objects
>
> Are you using strict and warnings? If not, turn them on. Here, you're
> trying to access a hash named %node, rather than a hashref named $node.
> Assuming @nodes does contain an array of hashes (or objects), this
> should be:
> print $node->{Name} . "\n";

@nodes is actually (or rather, supposed to be, but isn't, which is the
root of my problem) an array of OLE TreeNode objects. Looking at the
documentation again, I think you're right, the properties of an OLE
object are stored as a hashref, not a hash, and the it should be
$node->{Name}. At this time, though, neither works, because the @nodes
array is completely empty and the loop never gets entered.

I included the other guy's sample code I found related to this (copied
again below, with a few extra lines for clarification) because I
*think* that the answer is that I have to pass some kind of Variant to
the function. That's what he does to get a double value passed out of
the OLE method that takes an [out] parameter (a parameter that gets
changed within the OLE object method). But if I do that, what kind of
Variant do I pass in? And how do I get access to the OLE objects I get
back?

> use Win32::OLE;
> use Win32::OLE::Variant;
> my $arg4 = Variant( VT_R8 | VT_BYREF, 0.0);
> my $service = Win32::OLE->new( '3rdPartyComponent.Service' );
> $service->foo( 31, 4000, 28000, $arg4 );
> # That last parameter is a double, whose value gets altered within
> # and passed back out of the foo method of the $service object.

Thanks!