Discussion:
c++ dll with delphi variant args
(too old to reply)
Terry Thrift
2006-02-21 14:15:13 UTC
Permalink
Hi:

I'm working on a C++ DLL that is called from someone else's delphi app.

Delphi Interface
----------------
A delphi DLL interface that works is:

library FOOBAR;
function DLL(s: shortstring; var i,j,k,l,w,x,y,z: variant): variant;
stdcall;
begin
DLL:=2;
end;

exports
DLL;
begin
end.


C++Builder6 CPP Interface
---------------------
I attempted to translate the delphi DLL interface to CPP as follows:

Variant WINAPI DLL ( ShortString s, Variant &i, Variant &j, Variant &k,
Variant &l, Variant &w, Variant &x, Variant &y, Variant &z)
{
Variant vRet((int)2);
return vRet;
}

It compiles fine but does not return the correct value to the host
application.


Could someone please show me a correct translation of the above delphi
DLL interface to C++?

thx
-Terry Thrift-
Remy Lebeau (TeamB)
2006-02-21 18:36:29 UTC
Permalink
I do not suggest you use VCL types in exported functions from a C++ DLL.
Use Win32 API types instead, ie:

VARIANT WINAPI DLL(const char* s, VARIANT* i, VARIANT* j, VARIANT* k,
VARIANT* l, VARIANT* w, VARIANT* x, VARIANT* y, VARIANT* z)
{
VARIANT vRet;
::VariantInit(&vRet);
V_VT(&vRet) = VT_I4;
V_I4(&vRet) = 2;
return vRet;
}

In Delphi, you can then import the function like this:

function DLL(const s: PChar; var i, j, k, l, w, x, y, z: OleVariant):
OleVariant; stdcall; external 'thefile.dll'
Post by Terry Thrift
It compiles fine but does not return the correct value to the host
application.

Please elaborate.


Gambit
Terry Thrift
2006-02-21 20:51:00 UTC
Permalink
Hi Remy:

Thanks for the input.

Elaboration:
I license the use of a futures data charting app called Ensign software.
The application has an extension language called ESPL. Within that
language the user can invoke calls to a DLL stub. The exported function
of the DLL must meet the following specification (expressed in delphi as):

function DLL(s: shortstring; var i,j,k,l,w,x,y,z: variant): variant;
stdcall;

I am hoping that there is a practical way to deal with that interface
specification from C++.

To that end I came up with an inexperienced guess at what it should look
like in C++ that used references to Variants, a ShortString and WINAPI.


So maybe using VARIANT instead of Variant will get me closer to what I need?

Is it even possible to write a C++ DLL that meets that specification?

Thanks,
-Terry Thrift-
Post by Remy Lebeau (TeamB)
I do not suggest you use VCL types in exported functions from a C++ DLL.
VARIANT WINAPI DLL(const char* s, VARIANT* i, VARIANT* j, VARIANT* k,
VARIANT* l, VARIANT* w, VARIANT* x, VARIANT* y, VARIANT* z)
{
VARIANT vRet;
::VariantInit(&vRet);
V_VT(&vRet) = VT_I4;
V_I4(&vRet) = 2;
return vRet;
}
OleVariant; stdcall; external 'thefile.dll'
Post by Terry Thrift
It compiles fine but does not return the correct value to the host
application.
Please elaborate.
Gambit
Remy Lebeau (TeamB)
2006-02-21 23:37:28 UTC
Permalink
The exported function of the DLL must meet the following
specification
That was not very flexible of them to do that. They locked their design
into something that is easy accessible from Delphi only. Not that it is
impossible to use from C++, because it is not, but it is not as easy as with
Delphi. Did they think that only Delphi users would ever access their
application? They should have designed their interface better.
I am hoping that there is a practical way to deal with that
interface specification from C++.
Try creating a Package instead of a DLL. That is the only safe way to use
VCL types for parameters in exported DLL functions. Then your original code
might work:

Variant __stdcall DLL(ShortString s, Variant &i, Variant &j, Variant &k,
Variant &l, Variant &w, Variant &x, Variant &y, Variant &z)
{
return Variant((int)2);
}

You will still have to be careful, especially with compiler versions. The
VCL's Variants unit tends to undergo major re-writes between versions. If
your DLL is written in a different version than the application, who knows
what will happen.
To that end I came up with an inexperienced guess at what it
should look like in C++ that used references to Variants,
a ShortString and WINAPI.
Variant (upper-case V, everything else lower-case) and ShortString are VCL
types. They do not exist in the Win32 API.
So maybe using VARIANT instead of Variant will get me closer to what I need?
Doubtful. The Variant and VARIANT types are not directly compatible, at
least not entirely. That is why the OleVariant type exists - to mix the
VCL's Variant type with the Win32 API's VARIANT type.
Is it even possible to write a C++ DLL that meets that specification?
Not impossible, but not as easily implemented as with Delphi.


Gambit
Terry Thrift
2006-02-22 05:07:30 UTC
Permalink
Gambit/Remy:

Thankyou so much for your help.

I will investigate how to make a package instead of a dll. So, after
making the package foo.bpl, I can rename it foo.dll and their delphi
application might load/manage the package as if it were the expected
delphi dll?

Also I'll find out which version of delphi the application's author is
currently using, so I can use a c++ builder version of the same
generation to insure use of the same VCL version.

-Terry Thrift-
Post by Remy Lebeau (TeamB)
Post by Terry Thrift
I am hoping that there is a practical way to deal with that
interface specification from C++.
Try creating a Package instead of a DLL. That is the only safe way to use
VCL types for parameters in exported DLL functions. Then your original code
Variant __stdcall DLL(ShortString s, Variant &i, Variant &j, Variant &k,
Variant &l, Variant &w, Variant &x, Variant &y, Variant &z)
{
return Variant((int)2);
}
You will still have to be careful, especially with compiler versions. The
VCL's Variants unit tends to undergo major re-writes between versions. If
your DLL is written in a different version than the application, who knows
what will happen.
Gambit
Remy Lebeau (TeamB)
2006-02-22 23:13:30 UTC
Permalink
So, after making the package foo.bpl, I can rename it foo.dll and
their delphi application might load/manage the package as if it
were the expected delphi dll?
Only if their code is using the LoadPackage() function instead of
LoadLibrary(). Otherwise, the VCL will fail to operate properly in your
package.

I think you need to contact the developers of the application directly and
ask them about it.


Gambit

Loading...