Code Comments
Programming Forum and web based access to our favorite programming groups.Argument passing between perl and C function. There is C function in a OLE server: What kind of variable should I pass to this function? ######################################## ################################# BOOL Calculate(BSTR* names, double* values, short number_of_names); I tried the following script, but there is always an error like "Type mismatch" ... Is there any simple way to pass argument between perl and C function? ######################################## ################################# #! perl -W use strict; use Win32::OLE; use Win32::OLE::Variant; my $names =3D Variant(VT_BSTR|VT_ARRAY, 3); my $values =3D Variant(VT_R8|VT_ARRAY, 3); $names->Put(['name1', 'name2', 'name3']); $values->Put([0, 0, 0]); my $ret =3D $app->Calculate($names, $values, 3);
Post Follow-up to this messageJ, You need more information about the function that is contained in the IDL or the type library. Unfortunately, not all COM objects have an IDL file or type library. Both the IDL file and the type library would tell us exactly what the "*" means in C because it is ambiguous. The "*" could mean we are passing a single value by reference, or multiple values. I can tell you that it is not looking for a variant, however. Often COM uses a special data structure called a SAFEARRAY to pass arrays so it could be that your function is looking for scalars, not arrays. Perhaps there is some documentation? S -----Original Message----- From: J aperlh [mailto:japerlh@gmail.com] Sent: Wednesday, June 01, 2005 8:44 PM To: beginners@perl.org Subject: Argument passing between perl and a C function. Argument passing between perl and C function. There is C function in a OLE server: What kind of variable should I pass to this function? ######################################## ################################# BOOL Calculate(BSTR* names, double* values, short number_of_names); I tried the following script, but there is always an error like "Type mismatch" ... Is there any simple way to pass argument between perl and C function? ######################################## ################################# #! perl -W use strict; use Win32::OLE; use Win32::OLE::Variant; my $names = Variant(VT_BSTR|VT_ARRAY, 3); my $values = Variant(VT_R8|VT_ARRAY, 3); $names->Put(['name1', 'name2', 'name3']); $values->Put([0, 0, 0]); my $ret = $app->Calculate($names, $values, 3); -- To unsubscribe, e-mail: beginners-unsubscribe@perl.org For additional commands, e-mail: beginners-help@perl.org <http://learn.perl.org/> <http://learn.perl.org/first-response>
Post Follow-up to this message--------------------------------------------------------------------------- Thanks for you guys help. There is an application written in C language by my colleague. We are not allowed to share this application for security reason. What I am going to do is to call a set of functions in this application (OLE server) from a PERL script (OLE controller). So far, all the functions are works well, except a reference(pointer) related functions: --------------------------------------------------------------------------- BOOL Calculate(BSTR* names, double* values, short number_of_names); names: a list of names values: a list of corresponding values, number_of_names: size of the array I don't know that I should pass to this funtion. Array reference or something else? I know that if the OLE controller is in C language, things will be easier, Passing the first element of the array to this function is ok On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote: > J, > You need more information about the function that is contained in the IDL= or > the type library. Unfortunately, not all COM objects have an IDL file or > type library. >=20 > Both the IDL file and the type library would tell us exactly what the "*" > means in C because it is ambiguous. The "*" could mean we are passing a > single value by reference, or multiple values. >=20 > I can tell you that it is not looking for a variant, however. >=20 > Often COM uses a special data structure called a SAFEARRAY to pass arrays= so > it could be that your function is looking for scalars, not arrays. >=20 > Perhaps there is some documentation? >=20 > S >=20 > -----Original Message----- > From: J aperlh [mailto:japerlh@gmail.com] > Sent: Wednesday, June 01, 2005 8:44 PM > To: beginners@perl.org > Subject: Argument passing between perl and a C function. >=20 > Argument passing between perl and C function. >=20 >=20 > There is C function in a OLE server: > What kind of variable should I pass to this function? > ######################################## ################################# > BOOL Calculate(BSTR* names, double* values, short number_of_names); >=20 >=20 > I tried the following script, but there is always an error like "Type > mismatch" ... > Is there any simple way to pass argument between perl and C function? > ######################################## ################################# > #! perl -W >=20 >=20 > use strict; > use Win32::OLE; > use Win32::OLE::Variant; >=20 >=20 > my $names =3D Variant(VT_BSTR|VT_ARRAY, 3); > my $values =3D Variant(VT_R8|VT_ARRAY, 3); >=20 >=20 > $names->Put(['name1', 'name2', 'name3']); > $values->Put([0, 0, 0]); >=20 >=20 > my $ret =3D $app->Calculate($names, $values, 3); >=20 > -- > To unsubscribe, e-mail: beginners-unsubscribe@perl.org > For additional commands, e-mail: beginners-help@perl.org > <http://learn.perl.org/> <http://learn.perl.org/first-response> >=20 >=20 >
Post Follow-up to this messageJ, Is this a custom interface or a dispatch interface? I assumed it was a dispatch interface. Perl and many other languages like VB and javascript work well with dispatch interfaces because dispatch interfaces were specifically designed to accommodate languages like these. All dispatch interfaces are various implementations of IDispatch, a set of function prototypes defined my Microsoft. I think you have a custom interface because you are not using SAFEARRAYs. I doubt Win32::OLE can accommodate custom interfaces. Can you implement your object using a dispatch or dual interface? You might have to have the author of your COM object wrap it in C++ with a dispatch interface so you can call it from perl. Wraping it with a C++ dispatch interface is not hard with Visual Studio's code generators. I would not want to do it without visual studio, however. Custom interfaces are a big problem. Not even microsoft's most recent languages, VB.NET and C# can consistently call custom interfaces. I would not want to try to do so directly in perl. Siegfried -----Original Message----- From: J aperlh [mailto:japerlh@gmail.com] Sent: Thursday, June 02, 2005 7:59 PM To: Siegfried Heintze Cc: beginners@perl.org Subject: Re: Argument passing between perl and a C function. --------------------------------------------------------------------------- Thanks for you guys help. There is an application written in C language by my colleague. We are not allowed to share this application for security reason. What I am going to do is to call a set of functions in this application (OLE server) from a PERL script (OLE controller). So far, all the functions are works well, except a reference(pointer) related functions: --------------------------------------------------------------------------- BOOL Calculate(BSTR* names, double* values, short number_of_names); names: a list of names values: a list of corresponding values, number_of_names: size of the array I don't know that I should pass to this funtion. Array reference or something else? I know that if the OLE controller is in C language, things will be easier, Passing the first element of the array to this function is ok On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote: > J, > You need more information about the function that is contained in the IDL or > the type library. Unfortunately, not all COM objects have an IDL file or > type library. > > Both the IDL file and the type library would tell us exactly what the "*" > means in C because it is ambiguous. The "*" could mean we are passing a > single value by reference, or multiple values. > > I can tell you that it is not looking for a variant, however. > > Often COM uses a special data structure called a SAFEARRAY to pass arrays so > it could be that your function is looking for scalars, not arrays. > > Perhaps there is some documentation? > > S > > -----Original Message----- > From: J aperlh [mailto:japerlh@gmail.com] > Sent: Wednesday, June 01, 2005 8:44 PM > To: beginners@perl.org > Subject: Argument passing between perl and a C function. > > Argument passing between perl and C function. > > > There is C function in a OLE server: > What kind of variable should I pass to this function? > ######################################## ################################# > BOOL Calculate(BSTR* names, double* values, short number_of_names); > > > I tried the following script, but there is always an error like "Type > mismatch" ... > Is there any simple way to pass argument between perl and C function? > ######################################## ################################# > #! perl -W > > > use strict; > use Win32::OLE; > use Win32::OLE::Variant; > > > my $names = Variant(VT_BSTR|VT_ARRAY, 3); > my $values = Variant(VT_R8|VT_ARRAY, 3); > > > $names->Put(['name1', 'name2', 'name3']); > $values->Put([0, 0, 0]); > > > my $ret = $app->Calculate($names, $values, 3); > > -- > To unsubscribe, e-mail: beginners-unsubscribe@perl.org > For additional commands, e-mail: beginners-help@perl.org > <http://learn.perl.org/> <http://learn.perl.org/first-response> > > > -- To unsubscribe, e-mail: beginners-unsubscribe@perl.org For additional commands, e-mail: beginners-help@perl.org <http://learn.perl.org/> <http://learn.perl.org/first-response>
Post Follow-up to this messageSiegfried, Thank you. I am sure it's a dispatch interface. On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote: > J, > Is this a custom interface or a dispatch interface? I assumed it was a > dispatch interface. Perl and many other languages like VB and javascript > work well with dispatch interfaces because dispatch interfaces were > specifically designed to accommodate languages like these. >=20 > All dispatch interfaces are various implementations of IDispatch, a set o= f > function prototypes defined my Microsoft. >=20 > I think you have a custom interface because you are not using SAFEARRAYs.= I > doubt Win32::OLE can accommodate custom interfaces. Can you implement you= r > object using a dispatch or dual interface? You might have to have the aut= hor > of your COM object wrap it in C++ with a dispatch interface so you can ca= ll > it from perl. Wraping it with a C++ dispatch interface is not hard with > Visual Studio's code generators. I would not want to do it without visual > studio, however. >=20 > Custom interfaces are a big problem. Not even microsoft's most recent > languages, VB.NET and C# can consistently call custom interfaces. I would > not want to try to do so directly in perl. >=20 > Siegfried >=20 > -----Original Message----- > From: J aperlh [mailto:japerlh@gmail.com] > Sent: Thursday, June 02, 2005 7:59 PM > To: Siegfried Heintze > Cc: beginners@perl.org > Subject: Re: Argument passing between perl and a C function. >=20 > -------------------------------------------------------------------------= -- > Thanks for you guys help. >=20 > There is an application written in C language by my colleague. > We are not allowed to share this application for security reason. >=20 > What I am going to do is to call a set of functions in this > application (OLE server) from a PERL script (OLE controller). >=20 > So far, all the functions are works well, except a reference(pointer) > related functions: > -------------------------------------------------------------------------= -- > BOOL Calculate(BSTR* names, double* values, short number_of_names); > names: a list of names > values: a list of corresponding values, > number_of_names: size of the array >=20 > I don't know that I should pass to this funtion. > Array reference or something else? >=20 > I know that if the OLE controller is in C language, things will be easier= , > Passing the first element of the array to this function is ok >=20 >=20 >=20 > On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote: DL > or r *" ys > so ## ## >=20 > -- > To unsubscribe, e-mail: beginners-unsubscribe@perl.org > For additional commands, e-mail: beginners-help@perl.org > <http://learn.perl.org/> <http://learn.perl.org/first-response> >=20 >=20 >=20 > -- > To unsubscribe, e-mail: beginners-unsubscribe@perl.org > For additional commands, e-mail: beginners-help@perl.org > <http://learn.perl.org/> <http://learn.perl.org/first-response> >=20 >=20 >
Post Follow-up to this messageJ, I just reviewed the notes I used to teach COM from. I'm feeling more certain that if you want to pass arrays with the dispatch interface, you can either pass a variant or pass a SAFEARRAY. You appear to be doing neither in your C++ code. Sieg -----Original Message----- From: J aperlh [mailto:japerlh@gmail.com] Sent: Friday, June 03, 2005 12:05 AM To: Siegfried Heintze Cc: beginners@perl.org Subject: Re: Argument passing between perl and a C function. Siegfried, Thank you. I am sure it's a dispatch interface. On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote: > J, > Is this a custom interface or a dispatch interface? I assumed it was a > dispatch interface. Perl and many other languages like VB and javascript > work well with dispatch interfaces because dispatch interfaces were > specifically designed to accommodate languages like these. > > All dispatch interfaces are various implementations of IDispatch, a set of > function prototypes defined my Microsoft. > > I think you have a custom interface because you are not using SAFEARRAYs. I > doubt Win32::OLE can accommodate custom interfaces. Can you implement your > object using a dispatch or dual interface? You might have to have the author > of your COM object wrap it in C++ with a dispatch interface so you can call > it from perl. Wraping it with a C++ dispatch interface is not hard with > Visual Studio's code generators. I would not want to do it without visual > studio, however. > > Custom interfaces are a big problem. Not even microsoft's most recent > languages, VB.NET and C# can consistently call custom interfaces. I would > not want to try to do so directly in perl. > > Siegfried > > -----Original Message----- > From: J aperlh [mailto:japerlh@gmail.com] > Sent: Thursday, June 02, 2005 7:59 PM > To: Siegfried Heintze > Cc: beginners@perl.org > Subject: Re: Argument passing between perl and a C function. > > --------------------------------------------------------------------------- > Thanks for you guys help. > > There is an application written in C language by my colleague. > We are not allowed to share this application for security reason. > > What I am going to do is to call a set of functions in this > application (OLE server) from a PERL script (OLE controller). > > So far, all the functions are works well, except a reference(pointer) > related functions: > --------------------------------------------------------------------------- > BOOL Calculate(BSTR* names, double* values, short number_of_names); > names: a list of names > values: a list of corresponding values, > number_of_names: size of the array > > I don't know that I should pass to this funtion. > Array reference or something else? > > I know that if the OLE controller is in C language, things will be easier, > Passing the first element of the array to this function is ok > > > > On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote: IDL > or "*" arrays > so ######################################## #################################[color= darkred] ######################################## #################################[color= darkred] > > -- > To unsubscribe, e-mail: beginners-unsubscribe@perl.org > For additional commands, e-mail: beginners-help@perl.org > <http://learn.perl.org/> <http://learn.perl.org/first-response> > > > > -- > To unsubscribe, e-mail: beginners-unsubscribe@perl.org > For additional commands, e-mail: beginners-help@perl.org > <http://learn.perl.org/> <http://learn.perl.org/first-response> > > > -- To unsubscribe, e-mail: beginners-unsubscribe@perl.org For additional commands, e-mail: beginners-help@perl.org <http://learn.perl.org/> <http://learn.perl.org/first-response>
Post Follow-up to this messageSieg, Thanks for your help. I did not catch what you said. Should I change that application written in C++? Could you tell me something more about it? Thanks in advance. On 6/7/05, Siegfried Heintze <siegfried@heintze.com> wrote: > J, > I just reviewed the notes I used to teach COM from. I'm feeling more cert= ain > that if you want to pass arrays with the dispatch interface, you can eith= er > pass a variant or pass a SAFEARRAY. You appear to be doing neither in you= r > C++ code. > Sieg >=20 > -----Original Message----- > From: J aperlh [mailto:japerlh@gmail.com] > Sent: Friday, June 03, 2005 12:05 AM > To: Siegfried Heintze > Cc: beginners@perl.org > Subject: Re: Argument passing between perl and a C function. >=20 > Siegfried, >=20 > Thank you. > I am sure it's a dispatch interface. >=20 >=20 > On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote: t of s. > I our > author > call al ld > -------------------------------------------------------------------------= -- > -------------------------------------------------------------------------= -- er, > IDL or > "*" a > arrays > ######################################## ################################# > ######################################## ################################# >=20 > -- > To unsubscribe, e-mail: beginners-unsubscribe@perl.org > For additional commands, e-mail: beginners-help@perl.org > <http://learn.perl.org/> <http://learn.perl.org/first-response> >=20 >=20 >=20 --=20 Besh wishes, Japerlh
Post Follow-up to this messageJ,
I assume you are (1) successful at calling this function calculate from
C/C++ and (2) implementing this in a local DLL. Can you post a fragment of
this C/C++ client code?
I believe that you are successfully calling calculate from C/C++ in spite of
the fact you are breaking the rules of COM and specifically Dispatch
interfaces. I believe that if you were to implement calculate in an
executable or remote DLL on a different computer, it would not work because
you are breaking the rules.
I think the source of your confusion is that the rules of C (which say to
pass an array just pass a pointer) are not the same as COM Dispatch
interfaces. In COM dispatch interfaces, you do not pass a pointer for the
purpose of passing an array. You only pass a pointer for the purpose of
receiving a single scalar back from Calculate. I'm using the work scalar to
include BSTRs (i.e., strings).
To make your function receive arrays work, you have two options:
(1) Change the array arguments in your C/C++ source code to be variants.
This gets a little complicated because you can pass a variant by reference
or by value and a variant can contain a SAFEARRAY or a reference to a
SAFEARRAY and you probably should insert the logic to detect this and act
accordingly. Insert the code in function calculate to extract the SAFEARRY
from the variant. If you are using C/C++ as a client in addition to perl,
you will have to change this client C/C++ code too. I'm sure perl can handle
this approach.
(2) Change the array arguments to pass an SAFEARRAY by reference instead of
wrapping it in a variant. The code generator in Visual Studio does not do
this completely. You will have to manually edit the IDL code. I suspect perl
can handle this approach, but I'm not sure how to make perl send a safearray
without wrapping it in a variant. I found this technique documented only in
one place years ago, but I tried it (not with perl though) and it did work
and it is more efficient.
Both approaches require that you will have to enhance function calculate to
extract/store elements from your safearray. This requires you become
intimate with Microsoft's special functions for SAFEARRAYs.
You can find lots of books (probably out of print, however) and online
documentation on manipulating safearrays in C/C++. They are painful to use
from C/C++, however. You cannot use the bracket operators ('[]') to
fetch/store array elements unless you have a special package that overloades
the operator[] in C++. Microsoft supplies no such package, however.
If you have trouble with SAFEARRAYS, I am available for consulting services
for a fee. I could write some sample code for you, for example.
Good luck,
Siegfried
-----Original Message-----
From: Japerlh [mailto:japerlh@gmail.com]
Sent: Tuesday, June 07, 2005 1:23 AM
To: Siegfried Heintze
Cc: beginners@perl.org
Subject: Re: Argument passing between perl and a C function.
Sieg,
Thanks for your help.
I did not catch what you said.
Should I change that application written in C++?
Could you tell me something more about it?
Thanks in advance.
On 6/7/05, Siegfried Heintze <siegfried@heintze.com> wrote:
> J,
> I just reviewed the notes I used to teach COM from. I'm feeling more
certain
> that if you want to pass arrays with the dispatch interface, you can
either
> pass a variant or pass a SAFEARRAY. You appear to be doing neither in your
> C++ code.
> Sieg
>
> -----Original Message-----
> From: J aperlh [mailto:japerlh@gmail.com]
> Sent: Friday, June 03, 2005 12:05 AM
> To: Siegfried Heintze
> Cc: beginners@perl.org
> Subject: Re: Argument passing between perl and a C function.
>
> Siegfried,
>
> Thank you.
> I am sure it's a dispatch interface.
>
>
> On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote:
of
SAFEARRAYs.
> I
your
> author
> call
visual
would
>
---------------------------------------------------------------------------
>
---------------------------------------------------------------------------
easier,
> IDL
or
> "*"
a
> arrays
> ########################################
#################################
> ########################################
#################################
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>
>
--
Besh wishes,
Japerlh
--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>
Post Follow-up to this messageJ,
I forgot to mention something important: your perl code is sending a
SAFEARRAY. Perl creates and sends a SAFEARRAY when you create a variant with
VT_ARRAY. However, you are not receiving variants containing SAFEARRAYs in
your C/C++.
Good luck.
Siegfried
-----Original Message-----
From: Siegfried Heintze [mailto:siegfried@heintze.com]
Sent: Tuesday, June 07, 2005 11:50 AM
To: 'Japerlh'
Cc: beginners@perl.org
Subject: RE: Argument passing between perl and a C function.
J,
I assume you are (1) successful at calling this function calculate from
C/C++ and (2) implementing this in a local DLL. Can you post a fragment of
this C/C++ client code?
I believe that you are successfully calling calculate from C/C++ in spite of
the fact you are breaking the rules of COM and specifically Dispatch
interfaces. I believe that if you were to implement calculate in an
executable or remote DLL on a different computer, it would not work because
you are breaking the rules.
I think the source of your confusion is that the rules of C (which say to
pass an array just pass a pointer) are not the same as COM Dispatch
interfaces. In COM dispatch interfaces, you do not pass a pointer for the
purpose of passing an array. You only pass a pointer for the purpose of
receiving a single scalar back from Calculate. I'm using the work scalar to
include BSTRs (i.e., strings).
To make your function receive arrays work, you have two options:
(1) Change the array arguments in your C/C++ source code to be variants.
This gets a little complicated because you can pass a variant by reference
or by value and a variant can contain a SAFEARRAY or a reference to a
SAFEARRAY and you probably should insert the logic to detect this and act
accordingly. Insert the code in function calculate to extract the SAFEARRY
from the variant. If you are using C/C++ as a client in addition to perl,
you will have to change this client C/C++ code too. I'm sure perl can handle
this approach.
(2) Change the array arguments to pass an SAFEARRAY by reference instead of
wrapping it in a variant. The code generator in Visual Studio does not do
this completely. You will have to manually edit the IDL code. I suspect perl
can handle this approach, but I'm not sure how to make perl send a safearray
without wrapping it in a variant. I found this technique documented only in
one place years ago, but I tried it (not with perl though) and it did work
and it is more efficient.
Both approaches require that you will have to enhance function calculate to
extract/store elements from your safearray. This requires you become
intimate with Microsoft's special functions for SAFEARRAYs.
You can find lots of books (probably out of print, however) and online
documentation on manipulating safearrays in C/C++. They are painful to use
from C/C++, however. You cannot use the bracket operators ('[]') to
fetch/store array elements unless you have a special package that overloades
the operator[] in C++. Microsoft supplies no such package, however.
If you have trouble with SAFEARRAYS, I am available for consulting services
for a fee. I could write some sample code for you, for example.
Good luck,
Siegfried
-----Original Message-----
From: Japerlh [mailto:japerlh@gmail.com]
Sent: Tuesday, June 07, 2005 1:23 AM
To: Siegfried Heintze
Cc: beginners@perl.org
Subject: Re: Argument passing between perl and a C function.
Sieg,
Thanks for your help.
I did not catch what you said.
Should I change that application written in C++?
Could you tell me something more about it?
Thanks in advance.
On 6/7/05, Siegfried Heintze <siegfried@heintze.com> wrote:
> J,
> I just reviewed the notes I used to teach COM from. I'm feeling more
certain
> that if you want to pass arrays with the dispatch interface, you can
either
> pass a variant or pass a SAFEARRAY. You appear to be doing neither in your
> C++ code.
> Sieg
>
> -----Original Message-----
> From: J aperlh [mailto:japerlh@gmail.com]
> Sent: Friday, June 03, 2005 12:05 AM
> To: Siegfried Heintze
> Cc: beginners@perl.org
> Subject: Re: Argument passing between perl and a C function.
>
> Siegfried,
>
> Thank you.
> I am sure it's a dispatch interface.
>
>
> On 6/3/05, Siegfried Heintze <siegfried@heintze.com> wrote:
of
SAFEARRAYs.
> I
your
> author
> call
visual
would
>
---------------------------------------------------------------------------
>
---------------------------------------------------------------------------
easier,
> IDL
or
> "*"
a
> arrays
> ########################################
#################################
> ########################################
#################################
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>
>
--
Besh wishes,
Japerlh
--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>
--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.