Board index » delphi » How 2 Passing array of double to VB

How 2 Passing array of double to VB

Hi
I'm implementing a COM server in D6 to call from a VB client. I was handed
the typelib. An interface
contains a method:

function Thicknesses: OleVariant [propget, dispid $00000012, helpstring
'list of Thicknesses']; safecall;

According to the documentation, the result should be an array of doubles.

The Calling VB code looks like this:

Private Sub FillCBThicknesses
    On Error GoTo except

    CBThicknesses.Clear

     Dim i As Long
     Dim thicknesses As Variant
     thicknesses = interfaceref..Thicknesses
     If Not IsNull(thicknesses) Then
       For i = LBound(thicknesses) To UBound(thicknesses)
            CBlThicknesses.AddItem (interfaceref.Thicknesses(i))
        Next
     End If
    Exit Sub
End Sub

I tried implementing Get_Thicknesses like this:

type
 TOleStrArray = array of PWideChar;

function TDevice.Get_Thicknesses: OleVariant;
begin
     Result := VarArrayCreate([0,1], varDouble);
     Result[0] := 0.1;
     Result[1] := 0.2;
end;

When I run this though, the VB app throws an exception: "Could not convert
variant of type (String) into type (Double)"

I also tried using VT_R8 but got the same error. Some people have suggested
that
this is a SafeArray issue but I'm not sure what that means or how to
proceed.

Any ideas?

--
Thanks

Scott Kellish
MavenWare SoftSystem Solutions
skell...@comcast.net

 

Re:How 2 Passing array of double to VB


hi,

What VB wants is a SafeArray which is an array of element s of one specific
type. Like double. The Delphi VariantArray is an array of variants, VB
cannot detect the type of the individual elements there. For a larger story,
including a recipe how to implement a SafeArray see
http://www.gekko-software.nl/Delphi/art08.htm.

--
regards,

Peter.van.Ooi...@Gekko-Software.nl

http://www.Gekko-Software.nl/Delphi
http://www.Gekko-Software.nl/DotNet

Quote
"Scott Kellish" <skell...@siemens-hearing.com> wrote in message

news:3c853956$1_2@dnews...
Quote
> Hi
> I'm implementing a COM server in D6 to call from a VB client. I was handed
> the typelib. An interface
> contains a method:

> function Thicknesses: OleVariant [propget, dispid $00000012, helpstring
> 'list of Thicknesses']; safecall;

> According to the documentation, the result should be an array of doubles.

> The Calling VB code looks like this:

> Private Sub FillCBThicknesses
>     On Error GoTo except

>     CBThicknesses.Clear

>      Dim i As Long
>      Dim thicknesses As Variant
>      thicknesses = interfaceref..Thicknesses
>      If Not IsNull(thicknesses) Then
>        For i = LBound(thicknesses) To UBound(thicknesses)
>             CBlThicknesses.AddItem (interfaceref.Thicknesses(i))
>         Next
>      End If
>     Exit Sub
> End Sub

> I tried implementing Get_Thicknesses like this:

> type
>  TOleStrArray = array of PWideChar;

> function TDevice.Get_Thicknesses: OleVariant;
> begin
>      Result := VarArrayCreate([0,1], varDouble);
>      Result[0] := 0.1;
>      Result[1] := 0.2;
> end;

> When I run this though, the VB app throws an exception: "Could not convert
> variant of type (String) into type (Double)"

> I also tried using VT_R8 but got the same error. Some people have
suggested
> that
> this is a SafeArray issue but I'm not sure what that means or how to
> proceed.

> Any ideas?

> --
> Thanks

> Scott Kellish
> MavenWare SoftSystem Solutions
> skell...@comcast.net

Re:How 2 Passing array of double to VB


Thanks Peter,
I will take a look at the reference you sited. In light of VB wanting a
SafeArray, does it make sense that the interface method would expect an
OleVariant result? The guys who defined the typelib are VB programmers and
as such provided a test server and client both written in VB and both of
which they say work?

Thanks
Scott

"Peter van Ooijen" <Peter.van.Ooi...@Gekko-Software.nl> wrote in message
news:3c85d9b0$1_1@dnews...

Quote
> hi,

> What VB wants is a SafeArray which is an array of element s of one
specific
> type. Like double. The Delphi VariantArray is an array of variants, VB
> cannot detect the type of the individual elements there. For a larger
story,
> including a recipe how to implement a SafeArray see
> http://www.gekko-software.nl/Delphi/art08.htm.

> --
> regards,

> Peter.van.Ooi...@Gekko-Software.nl

> http://www.Gekko-Software.nl/Delphi
> http://www.Gekko-Software.nl/DotNet

> "Scott Kellish" <skell...@siemens-hearing.com> wrote in message
> news:3c853956$1_2@dnews...
> > Hi
> > I'm implementing a COM server in D6 to call from a VB client. I was
handed
> > the typelib. An interface
> > contains a method:

> > function Thicknesses: OleVariant [propget, dispid $00000012, helpstring
> > 'list of Thicknesses']; safecall;

> > According to the documentation, the result should be an array of
doubles.

> > The Calling VB code looks like this:

> > Private Sub FillCBThicknesses
> >     On Error GoTo except

> >     CBThicknesses.Clear

> >      Dim i As Long
> >      Dim thicknesses As Variant
> >      thicknesses = interfaceref..Thicknesses
> >      If Not IsNull(thicknesses) Then
> >        For i = LBound(thicknesses) To UBound(thicknesses)
> >             CBlThicknesses.AddItem (interfaceref.Thicknesses(i))
> >         Next
> >      End If
> >     Exit Sub
> > End Sub

> > I tried implementing Get_Thicknesses like this:

> > type
> >  TOleStrArray = array of PWideChar;

> > function TDevice.Get_Thicknesses: OleVariant;
> > begin
> >      Result := VarArrayCreate([0,1], varDouble);
> >      Result[0] := 0.1;
> >      Result[1] := 0.2;
> > end;

> > When I run this though, the VB app throws an exception: "Could not
convert
> > variant of type (String) into type (Double)"

> > I also tried using VT_R8 but got the same error. Some people have
> suggested
> > that
> > this is a SafeArray issue but I'm not sure what that means or how to
> > proceed.

> > Any ideas?

> > --
> > Thanks

> > Scott Kellish
> > MavenWare SoftSystem Solutions
> > skell...@comcast.net

Re:How 2 Passing array of double to VB


hi Scott,

no, I don't think VB wants a OleVariant. It want's a SafeArray which is an
automatable type on itself. You can pick it as a type in the typelib-editor.
The confusion is that what VB names a safearray is not the same as a Delphi
variantarray.

Peter

Quote
"Scott Kellish" <skell...@siemens-hearing.com> wrote in message

news:3c861742$1_2@dnews...
Quote
> Thanks Peter,
> I will take a look at the reference you sited. In light of VB wanting a
> SafeArray, does it make sense that the interface method would expect an
> OleVariant result? The guys who defined the typelib are VB programmers and
> as such provided a test server and client both written in VB and both of
> which they say work?

> Thanks
> Scott

> "Peter van Ooijen" <Peter.van.Ooi...@Gekko-Software.nl> wrote in message
> news:3c85d9b0$1_1@dnews...
> > hi,

> > What VB wants is a SafeArray which is an array of element s of one
> specific
> > type. Like double. The Delphi VariantArray is an array of variants, VB
> > cannot detect the type of the individual elements there. For a larger
> story,
> > including a recipe how to implement a SafeArray see
> > http://www.gekko-software.nl/Delphi/art08.htm.

> > --
> > regards,

> > Peter.van.Ooi...@Gekko-Software.nl

> > http://www.Gekko-Software.nl/Delphi
> > http://www.Gekko-Software.nl/DotNet

> > "Scott Kellish" <skell...@siemens-hearing.com> wrote in message
> > news:3c853956$1_2@dnews...
> > > Hi
> > > I'm implementing a COM server in D6 to call from a VB client. I was
> handed
> > > the typelib. An interface
> > > contains a method:

> > > function Thicknesses: OleVariant [propget, dispid $00000012,
helpstring
> > > 'list of Thicknesses']; safecall;

> > > According to the documentation, the result should be an array of
> doubles.

> > > The Calling VB code looks like this:

> > > Private Sub FillCBThicknesses
> > >     On Error GoTo except

> > >     CBThicknesses.Clear

> > >      Dim i As Long
> > >      Dim thicknesses As Variant
> > >      thicknesses = interfaceref..Thicknesses
> > >      If Not IsNull(thicknesses) Then
> > >        For i = LBound(thicknesses) To UBound(thicknesses)
> > >             CBlThicknesses.AddItem (interfaceref.Thicknesses(i))
> > >         Next
> > >      End If
> > >     Exit Sub
> > > End Sub

> > > I tried implementing Get_Thicknesses like this:

> > > type
> > >  TOleStrArray = array of PWideChar;

> > > function TDevice.Get_Thicknesses: OleVariant;
> > > begin
> > >      Result := VarArrayCreate([0,1], varDouble);
> > >      Result[0] := 0.1;
> > >      Result[1] := 0.2;
> > > end;

> > > When I run this though, the VB app throws an exception: "Could not
> convert
> > > variant of type (String) into type (Double)"

> > > I also tried using VT_R8 but got the same error. Some people have
> > suggested
> > > that
> > > this is a SafeArray issue but I'm not sure what that means or how to
> > > proceed.

> > > Any ideas?

> > > --
> > > Thanks

> > > Scott Kellish
> > > MavenWare SoftSystem Solutions
> > > skell...@comcast.net

Re:How 2 Passing array of double to VB


Hi Peter,
Actually its working ok now. At least in D6, Delphi's support for Variants
wrap around safearrays, so I was able to just return a VarArrayCreate
variant. My problem (and the error message) was because I had the following
line of code in the method for debugging.
ShowMessage('IDevice.Get_Thickness <--'+Result); I suppose that changing the
typelib from OleVariant to PSafeArray(Double) would just optimize the call?

Scott

"Peter van Ooijen" <Peter.van.Ooi...@Gekko-Software.nl> wrote in message
news:3c8637e1$1_1@dnews...

Quote
> hi Scott,

> no, I don't think VB wants a OleVariant. It want's a SafeArray which is an
> automatable type on itself. You can pick it as a type in the
typelib-editor.
> The confusion is that what VB names a safearray is not the same as a
Delphi
> variantarray.

> Peter

> "Scott Kellish" <skell...@siemens-hearing.com> wrote in message
> news:3c861742$1_2@dnews...
> > Thanks Peter,
> > I will take a look at the reference you sited. In light of VB wanting a
> > SafeArray, does it make sense that the interface method would expect an
> > OleVariant result? The guys who defined the typelib are VB programmers
and
> > as such provided a test server and client both written in VB and both of
> > which they say work?

> > Thanks
> > Scott

> > "Peter van Ooijen" <Peter.van.Ooi...@Gekko-Software.nl> wrote in message
> > news:3c85d9b0$1_1@dnews...
> > > hi,

> > > What VB wants is a SafeArray which is an array of element s of one
> > specific
> > > type. Like double. The Delphi VariantArray is an array of variants, VB
> > > cannot detect the type of the individual elements there. For a larger
> > story,
> > > including a recipe how to implement a SafeArray see
> > > http://www.gekko-software.nl/Delphi/art08.htm.

> > > --
> > > regards,

> > > Peter.van.Ooi...@Gekko-Software.nl

> > > http://www.Gekko-Software.nl/Delphi
> > > http://www.Gekko-Software.nl/DotNet

> > > "Scott Kellish" <skell...@siemens-hearing.com> wrote in message
> > > news:3c853956$1_2@dnews...
> > > > Hi
> > > > I'm implementing a COM server in D6 to call from a VB client. I was
> > handed
> > > > the typelib. An interface
> > > > contains a method:

> > > > function Thicknesses: OleVariant [propget, dispid $00000012,
> helpstring
> > > > 'list of Thicknesses']; safecall;

> > > > According to the documentation, the result should be an array of
> > doubles.

> > > > The Calling VB code looks like this:

> > > > Private Sub FillCBThicknesses
> > > >     On Error GoTo except

> > > >     CBThicknesses.Clear

> > > >      Dim i As Long
> > > >      Dim thicknesses As Variant
> > > >      thicknesses = interfaceref..Thicknesses
> > > >      If Not IsNull(thicknesses) Then
> > > >        For i = LBound(thicknesses) To UBound(thicknesses)
> > > >             CBlThicknesses.AddItem (interfaceref.Thicknesses(i))
> > > >         Next
> > > >      End If
> > > >     Exit Sub
> > > > End Sub

> > > > I tried implementing Get_Thicknesses like this:

> > > > type
> > > >  TOleStrArray = array of PWideChar;

> > > > function TDevice.Get_Thicknesses: OleVariant;
> > > > begin
> > > >      Result := VarArrayCreate([0,1], varDouble);
> > > >      Result[0] := 0.1;
> > > >      Result[1] := 0.2;
> > > > end;

> > > > When I run this though, the VB app throws an exception: "Could not
> > convert
> > > > variant of type (String) into type (Double)"

> > > > I also tried using VT_R8 but got the same error. Some people have
> > > suggested
> > > > that
> > > > this is a SafeArray issue but I'm not sure what that means or how to
> > > > proceed.

> > > > Any ideas?

> > > > --
> > > > Thanks

> > > > Scott Kellish
> > > > MavenWare SoftSystem Solutions
> > > > skell...@comcast.net

Re:How 2 Passing array of double to VB


hi,

if it is not broken don't fix it.
Changing the type in the typelibrary could have consequences. The internals
of a PSafeArray(double) are different form a Delphi VariantArray. It's time
I got VB installed, I allways test with VBA. Every client behaves diiferrent
when it comes to arrays. VBscript is mere hell.

Peter

Quote
"Scott Kellish" <skell...@siemens-hearing.com> wrote in message

news:3c8645ad$1_1@dnews...
Quote
> Hi Peter,
> Actually its working ok now. At least in D6, Delphi's support for Variants
> wrap around safearrays, so I was able to just return a VarArrayCreate
> variant. My problem (and the error message) was because I had the
following
> line of code in the method for debugging.
> ShowMessage('IDevice.Get_Thickness <--'+Result); I suppose that changing
the
> typelib from OleVariant to PSafeArray(Double) would just optimize the
call?

> Scott

> "Peter van Ooijen" <Peter.van.Ooi...@Gekko-Software.nl> wrote in message
> news:3c8637e1$1_1@dnews...
> > hi Scott,

> > no, I don't think VB wants a OleVariant. It want's a SafeArray which is
an
> > automatable type on itself. You can pick it as a type in the
> typelib-editor.
> > The confusion is that what VB names a safearray is not the same as a
> Delphi
> > variantarray.

> > Peter

> > "Scott Kellish" <skell...@siemens-hearing.com> wrote in message
> > news:3c861742$1_2@dnews...
> > > Thanks Peter,
> > > I will take a look at the reference you sited. In light of VB wanting
a
> > > SafeArray, does it make sense that the interface method would expect
an
> > > OleVariant result? The guys who defined the typelib are VB programmers
> and
> > > as such provided a test server and client both written in VB and both
of
> > > which they say work?

> > > Thanks
> > > Scott

> > > "Peter van Ooijen" <Peter.van.Ooi...@Gekko-Software.nl> wrote in
message
> > > news:3c85d9b0$1_1@dnews...
> > > > hi,

> > > > What VB wants is a SafeArray which is an array of element s of one
> > > specific
> > > > type. Like double. The Delphi VariantArray is an array of variants,
VB
> > > > cannot detect the type of the individual elements there. For a
larger
> > > story,
> > > > including a recipe how to implement a SafeArray see
> > > > http://www.gekko-software.nl/Delphi/art08.htm.

> > > > --
> > > > regards,

> > > > Peter.van.Ooi...@Gekko-Software.nl

> > > > http://www.Gekko-Software.nl/Delphi
> > > > http://www.Gekko-Software.nl/DotNet

> > > > "Scott Kellish" <skell...@siemens-hearing.com> wrote in message
> > > > news:3c853956$1_2@dnews...
> > > > > Hi
> > > > > I'm implementing a COM server in D6 to call from a VB client. I
was
> > > handed
> > > > > the typelib. An interface
> > > > > contains a method:

> > > > > function Thicknesses: OleVariant [propget, dispid $00000012,
> > helpstring
> > > > > 'list of Thicknesses']; safecall;

> > > > > According to the documentation, the result should be an array of
> > > doubles.

> > > > > The Calling VB code looks like this:

> > > > > Private Sub FillCBThicknesses
> > > > >     On Error GoTo except

> > > > >     CBThicknesses.Clear

> > > > >      Dim i As Long
> > > > >      Dim thicknesses As Variant
> > > > >      thicknesses = interfaceref..Thicknesses
> > > > >      If Not IsNull(thicknesses) Then
> > > > >        For i = LBound(thicknesses) To UBound(thicknesses)
> > > > >             CBlThicknesses.AddItem (interfaceref.Thicknesses(i))
> > > > >         Next
> > > > >      End If
> > > > >     Exit Sub
> > > > > End Sub

> > > > > I tried implementing Get_Thicknesses like this:

> > > > > type
> > > > >  TOleStrArray = array of PWideChar;

> > > > > function TDevice.Get_Thicknesses: OleVariant;
> > > > > begin
> > > > >      Result := VarArrayCreate([0,1], varDouble);
> > > > >      Result[0] := 0.1;
> > > > >      Result[1] := 0.2;
> > > > > end;

> > > > > When I run this though, the VB app throws an exception: "Could not
> > > convert
> > > > > variant of type (String) into type (Double)"

> > > > > I also tried using VT_R8 but got the same error. Some people have
> > > > suggested
> > > > > that
> > > > > this is a SafeArray issue but I'm not sure what that means or how
to
> > > > > proceed.

> > > > > Any ideas?

> > > > > --
> > > > > Thanks

> > > > > Scott Kellish
> > > > > MavenWare SoftSystem Solutions
> > > > > skell...@comcast.net

Other Threads