Board index » delphi » Safearray continued

Safearray continued

Hi Deborah

Thank you so much for the help! I tried your suggestion, but it still gives
a "Type not allowed in a OLE automation call". I'm trying to send a matrix
to MATLAB which requires the following in the call -

void PutFullMatrix(
                                [in] BSTR {Name},
                                [in] BSTR {Workspace},
                                [in] SAFEARRAY(double) {real number},
                                [in] SAFEARRAY(double) {imaginary number})

My little Delphi app looks like this -

var

 MReal : OleVariant;
 MImage : OleVariant;
 i : integer;

begin

 MImage := VarArrayCreate([0, 4], varempty);
 MReal := VarArrayCreate([0, 4], varinteger);

  for j := 0 to 4 do
   MReal[j] := j;

 V := CreateOLEObject('Matlab.Application');
 V.PutFullmatrix('a','base',TVarData(MReal).VArray,TVarData(MImage).VArray);

Trying to send a VarArray gives a "type mismatch" error in the execution.
Creating a psafearray with CreateSafeArray and trying to pass that gives an
"Type not allowed in a OLE automation call".

Thank you once again for all your help. As soon as I get this sorted out, I
will send the info for Matlab automation to your wonderful site.

Best wishes

Alex

 

Re:Safearray continued


<<Alex Conradie:
V.PutFullmatrix('a','base',TVarData(MReal).VArray,TVarData(
MImage).VArray);

Trying to send a VarArray gives a "type mismatch" error in
the execution.

Quote

OK, can you do
V.PutFullmatrix('a','base',
                PSafeArray(TVarData(MReal).VArray),        
         PSafeArray(TVarData(MImage).VArray));

--
Deborah Pate

Re:Safearray continued


Hi there again

V.PutFullmatrix('a','base',
                 PSafeArray(TVarData(MReal).VArray),
          PSafeArray(TVarData(MImage).VArray));

The above also gives me a "Type not allowed in OLE automation call" error.
Thanks so much for your suggestions. I don't know what I'm going to do to
make it work. In the Delphi help it has the following -
"COM requires that arrays be passed via a special data type known as a
SafeArray.  The Delphi compiler has built-in knowledge of COM SafeArrays and
will automatically call the COM API to create, copy, and destroy
SafeArrays."

If all arrays are automatically passed as safearrays, this implies that
Vararrays must be automatically converted? But trying to pass actual
safearrays has a OLE clash and sending Vararrays has a type mismatch. Weird!

Thank you for your kindness.

Alex

Quote
Deborah Pate <d.p...@cableinet.co.not-this-bit.uk> wrote in message

news:VA.0000001b.00199643@cableinet.co.not-this-bit.uk...
Quote
> <<Alex Conradie:
> V.PutFullmatrix('a','base',TVarData(MReal).VArray,TVarData(
> MImage).VArray);

> Trying to send a VarArray gives a "type mismatch" error in
> the execution.

> OK, can you do

> --
> Deborah Pate

Re:Safearray continued


<<Alex Conradie:
The above also gives me a "Type not allowed in OLE
automation call" error.

Quote

Drat, I didn't notice that you were using variants. If you
create an automation object with a method that takes a
psafearray parameter and look at the tlb.pas file, you'll
see something like this:

  IMyAutoObj = interface(IDispatch)
    ['{97B1E045-235B-11D4-B033-444553540001}']
    procedure SafeArrayTest(IntArray: PSafeArray);
safecall;
  end;
..
  IMyAutoObjDisp = dispinterface
    ['{97B1E045-235B-11D4-B033-444553540001}']
    procedure SafeArrayTest(IntArray: {??PSafeArray}
OleVariant); dispid 1;
  end;

You see it's only the dispinterface that causes this
problem. Have you a real interface that you could use for
this method? It wouldn't stop you creating the thing as a
variant, you could just do something like

  Disp: IDispatch;
..
  Disp := V;
  (Disp as IMyAutoObj).SafeArrayTest(
                  PSafeArray(TVarData(AV).VArray));

I haven't worked out how to pass the thing to a
dispinterface, but perhaps someone else will chip in.
One other thing: the IDL suggests you need an array of
double, but you're creating an array of integers. I don't
know if that will cause trouble.

--
Deborah Pate

Re:Safearray continued


Hi

I am creating an array of doubles. I still get the type mismatch. The
integer assignment was a typo. Sorry for the confusion.

I'll try the below soonest. Thank you.

Alex

Quote
Deborah Pate <d.p...@cableinet.co.not-this-bit.uk> wrote in message

news:VA.0000001d.003684f0@cableinet.co.not-this-bit.uk...
Quote
> <<Alex Conradie:
> The above also gives me a "Type not allowed in OLE
> automation call" error.

> Drat, I didn't notice that you were using variants. If you
> create an automation object with a method that takes a
> psafearray parameter and look at the tlb.pas file, you'll
> see something like this:

>   IMyAutoObj = interface(IDispatch)
>     ['{97B1E045-235B-11D4-B033-444553540001}']
>     procedure SafeArrayTest(IntArray: PSafeArray);
> safecall;
>   end;
> ..
>   IMyAutoObjDisp = dispinterface
>     ['{97B1E045-235B-11D4-B033-444553540001}']
>     procedure SafeArrayTest(IntArray: {??PSafeArray}
> OleVariant); dispid 1;
>   end;

> You see it's only the dispinterface that causes this
> problem. Have you a real interface that you could use for
> this method? It wouldn't stop you creating the thing as a
> variant, you could just do something like

>   Disp: IDispatch;
> ..
>   Disp := V;
>   (Disp as IMyAutoObj).SafeArrayTest(
>                   PSafeArray(TVarData(AV).VArray));

> I haven't worked out how to pass the thing to a
> dispinterface, but perhaps someone else will chip in.
> One other thing: the IDL suggests you need an array of
> double, but you're creating an array of integers. I don't
> know if that will cause trouble.

> --
> Deborah Pate

Re:Safearray continued


Hi everyone

The answer is below thanks to Binh Ly of http://www.techvanguards.com. Works
like a charm. The Varrayref function is the key.

procedure TForm1.Button1Click(Sender: TObject);

var

 MReal : OleVariant;
 MImage : OleVariant;

 i,j : integer;

begin

 MReal  := VarArrayCreate([0, 1, 0, 3], varDouble);
 MImage := VarArrayCreate([0,0,0,0], varDouble);

 for i := 0 to 1 do
  for j := 0 to 3 do
   MReal[i,j] := i*j;

 V := CreateOLEObject('Matlab.Application');

 V.PutFullmatrix('a','base',VarArrayRef(MReal),VararrayRef(MImage));

end;

Quote
Alex Conradie <aconr...@ing.sun.ac.za> wrote in message

news:3959f7c7@dnews...
Quote
> Hi

> I am creating an array of doubles. I still get the type mismatch. The
> integer assignment was a typo. Sorry for the confusion.

> I'll try the below soonest. Thank you.

> Alex

> Deborah Pate <d.p...@cableinet.co.not-this-bit.uk> wrote in message
> news:VA.0000001d.003684f0@cableinet.co.not-this-bit.uk...
> > <<Alex Conradie:
> > The above also gives me a "Type not allowed in OLE
> > automation call" error.

> > Drat, I didn't notice that you were using variants. If you
> > create an automation object with a method that takes a
> > psafearray parameter and look at the tlb.pas file, you'll
> > see something like this:

> >   IMyAutoObj = interface(IDispatch)
> >     ['{97B1E045-235B-11D4-B033-444553540001}']
> >     procedure SafeArrayTest(IntArray: PSafeArray);
> > safecall;
> >   end;
> > ..
> >   IMyAutoObjDisp = dispinterface
> >     ['{97B1E045-235B-11D4-B033-444553540001}']
> >     procedure SafeArrayTest(IntArray: {??PSafeArray}
> > OleVariant); dispid 1;
> >   end;

> > You see it's only the dispinterface that causes this
> > problem. Have you a real interface that you could use for
> > this method? It wouldn't stop you creating the thing as a
> > variant, you could just do something like

> >   Disp: IDispatch;
> > ..
> >   Disp := V;
> >   (Disp as IMyAutoObj).SafeArrayTest(
> >                   PSafeArray(TVarData(AV).VArray));

> > I haven't worked out how to pass the thing to a
> > dispinterface, but perhaps someone else will chip in.
> > One other thing: the IDL suggests you need an array of
> > double, but you're creating an array of integers. I don't
> > know if that will cause trouble.

> > --
> > Deborah Pate

Other Threads