OLE Error when Returning an empty Safearray to Perl Client

Posted by KevinG on 2006-10-10 07:40

Hi all,

I am having some trouble returning a 1D Safearray to a Perl client, everything is OK when the array has some elements, but if the array is empty I get the following error:

Win32::OLE(0.1704) error 0x8002000b: "Invalid index"

The function in question is declared as:

HRESULT GetBoardInspectionResults([out, retval] VARIANT* boardInspectionResults);

While the Perl Code that uses it looks like:

my $arr = $fis->GetBoardInspectionResults();
print "Array size: @$arr\n";

The error happens on the first line (only when the array is empty)

I have been unable to find a fix, the OLE function works OK for an empty array in VB & VB script etc. I wonder if am I am missing something, is it possible to return an empty array to Perl? It's strange, when the array has some elements then everything is just fine!

Any help would be greatly appreciated!

KevinG

KevinG | Wed, 2006-10-11 02:41

Hi All,

I think that my previous post might have been a little short on details! so I thought I would including some cut-down sample code to help explain the problem, I am using Active State Perl Version 5.8.8, Build 819. I am testing under windows XP, service pack 2, and I am building my OLE interface with Visual Studio 6, SP6.

I have created a cut-down COM object to test the problem, its interface supports IDispatch and is OLE Automation compatible. In the IDL file the test method is declared as:

[id(1), helpstring("method GetArray")] HRESULT GetArray([in] int elementCount, [out, retval] VARIANT* pV);

This method returns a SAFEARRAY in a Variant, the elementCount argument indicates how many elements should be placed in the array before it is returned.

This is how GetArray() is defined, it creates a Safearray of type VT_I4:

STDMETHODIMP CTestOutArray::GetArray(int elementCount, VARIANT *pV)
{
        V_VT(pV)= VT_ARRAY | VT_I4;

        SAFEARRAYBOUND saBound;
        saBound.lLbound = 0;
        saBound.cElements = elementCount;

        SAFEARRAY* pA = SafeArrayCreate(VT_I4, 1, &saBound);

        V_ARRAY(pV) = pA;

        if (elementCount > 0)
        {
                long index = 0;
                long val = 1234;

                SafeArrayPutElement(pA, &index, &val);
        }

        return S_OK;
}

I have got rid of any error checking code etc. to make it a bit easier to read...

When I call this from Perl with elementCount > 0, everything works OK, but when I call it with elementCount == 0 I get the 'Invalid Index' error:

Win32::OLE(0.1704) error 0x8002000b: "Invalid index" at C:/Projects/FIS/Perl/TestProj/TestOutArray.pl line 11

here is the client Perl Code:

use strict;

use Win32::OLE qw(in with);
$Win32::OLE::Warn = 3;

my $test = Win32::OLE->new('PerlOutArrayTest.TestOutArray', 'Quit') or die "Couldn't create object";

my $arr = $test->GetArray(1);  # Works OK
my $second_arr = $test->GetArray(0);  # Throws an error

Can anybody spot if I am doing something wrong? Should Perl work OK when an OLE method returns an empty Safearray, or should I just expect it to throw this error when the array is empty?

It's a bit of a pain as I sometimes need to return an empty array as part of normal operation, and I don't want to have to add loads of nasty extra code just to handle the situation!

Thanks Again!

Kevin Godden.