Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

interoperable dll

14 views
Skip to first unread message

Jorge Almeida

unread,
Feb 23, 2008, 12:06:50 AM2/23/08
to
I need to make dll to wrap up some functions the signatures below:

function envolve(const txt: widestring): widestring;
function devolve(const txt: widestring): widestring;

The dll functions to be called from VB6, Delphi Win32, VS .NET (c#, VB). The output length is not known until whole string coded all though usualy envolve output smaller than input and devolve output larger than input. The input to envolve is unicode character string and the output by devolve is unicode character string. Strings could be may be 1 to 25 MB.

To make Delphi Win32 dll really simple:

function envolve(const txt: widestring): widestring; cdecl;
function devolve(const txt: widestring): widestring; cdecl;

exports envolve;
exports devolve;

How does the VB6 and C# and .netVB developer use this, or do I make other wrapper? I reading that VB6 string type is Bstring or Widestring compatible, but VB6 developer get access violations to use.

Thank you for suggestions advise.

--
Jorge

Peter Below (TeamB)

unread,
Feb 23, 2008, 3:58:08 AM2/23/08
to
Jorge Almeida wrote:

> I need to make dll to wrap up some functions the signatures below:
>
> function envolve(const txt: widestring): widestring;
> function devolve(const txt: widestring): widestring;
>
> The dll functions to be called from VB6, Delphi Win32, VS .NET (c#,
> VB). The output length is not known until whole string coded all
> though usualy envolve output smaller than input and devolve output
> larger than input. The input to envolve is unicode character string
> and the output by devolve is unicode character string. Strings could
> be may be 1 to 25 MB.
>
> To make Delphi Win32 dll really simple:
>
> function envolve(const txt: widestring): widestring; cdecl;
> function devolve(const txt: widestring): widestring; cdecl;

You cannot use the cdecl calling convention if you want the DLL to be
VB6 compatible. Use stdcall, that is the only calling convention VB6
can use. Returning a widestring result is a bit problematic. Delphi
codes these functions as if they were declared as

procedure envolve(const txt: widestring; var result: widestring);

which is probably not the same way VB6 or a .NET language would do it.
The "const" attribute is also something that has no meaning for VB6.
The way the Delphi compiler passes a const widestring is in fact the
same as passing a var widestring: it passes the address of the
widestring variable, that is a BSTR FAR* in API (C) lingo. I think that
is the same mechanism VB6 uses to pass a byref string.

So my advice is to declare the routines as

procedure envolve(const txt: widestring; var result: widestring);
stdcall;
procedure devolve(const txt: widestring; var result: widestring);
stdcall;

which should translate to

declare sub envolve lib "somedllname" (byref txt as string, byref
result as string)
declare sub devolve lib "somedllname" (byref txt as string, byref
result as string)

for VB6.

To use this DLL from a .NET language you need a declaration of the
procedures in the .NET language, which specifies parameter types and
calling conventions using attributes. It should be something like this,
but don't take it at face value, my C# is pretty rudimentary <g>

[DllImport("yourdllname.dll")]
public static extern void envolve([MarshalAs(UnmanagedType.BStr)] ref
string txt, [MarshalAs(UnmanagedType.BStr) ref string result);

See http://msdn2.microsoft.com/en-us/library/aa288468.aspx, i'm not
sure if the marshalling would need the in and out attributes specified
to get the reference parameters across correctly.

--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com

Rob Kennedy

unread,
Feb 23, 2008, 12:06:29 PM2/23/08
to
Peter Below (TeamB) wrote:
> procedure envolve(const txt: widestring; var result: widestring);
>
> which is probably not the same way VB6 or a .NET language would do it.
> The "const" attribute is also something that has no meaning for VB6.
> The way the Delphi compiler passes a const widestring is in fact the
> same as passing a var widestring: it passes the address of the
> widestring variable, that is a BSTR FAR* in API (C) lingo.

I'm pretty sure that's not how a const WideString is passed. A const
WideString is passed just like a non-const WideString, isn't it? The
pointer to the string's first character is placed directly on the stack,
just like passing an AnsiString. The "const" just determines whether the
function will create a local copy of the string.

--
Rob

Jorge Almeida

unread,
Feb 23, 2008, 2:34:16 PM2/23/08
to
Peter Below (TeamB) wrote:

> So my advice is to declare the routines as
>
> procedure envolve(const txt: widestring; var result: widestring);
> stdcall;
> procedure devolve(const txt: widestring; var result: widestring);
> stdcall;
>
> which should translate to
>
> declare sub envolve lib "somedllname" (byref txt as string, byref
> result as string)
> declare sub devolve lib "somedllname" (byref txt as string, byref
> result as string)

Thank you sir. The VB6 now working. I owe you.

--
Jorge

Peter Below (TeamB)

unread,
Feb 23, 2008, 2:30:23 PM2/23/08
to
Rob Kennedy wrote:

> Peter Below (TeamB) wrote:
> > procedure envolve(const txt: widestring; var result: widestring);
> >
> > which is probably not the same way VB6 or a .NET language would do
> > it. The "const" attribute is also something that has no meaning
> > for VB6. The way the Delphi compiler passes a const widestring is
> > in fact the same as passing a var widestring: it passes the address
> > of the widestring variable, that is a BSTR FAR* in API (C) lingo.
>
> I'm pretty sure that's not how a const WideString is passed.

It is, trust me <g>. I looked at the generated code for a test call to
a procedure declared as above since I could not find a definitive
statement of how widestrings are handled in the Delphi Language Guide.

Robert Morley

unread,
Feb 23, 2008, 6:17:35 PM2/23/08
to
Peter Below (TeamB) wrote:
> You cannot use the cdecl calling convention if you want the DLL to be
> VB6 compatible. Use stdcall, that is the only calling convention VB6
> can use.

I'm nowhere near writing my own Delphi DLLs for VB6 yet, but just for
clarification, does "stdcall" create COM-compatible calls
(MyDll.MyFunction), or do you have to use API-style declarations (Public
Declare MyFunction "MyDll"...) in VB6?

Thanks,
Rob

Marc Rohloff [TeamB]

unread,
Feb 23, 2008, 6:44:55 PM2/23/08
to
On Sat, 23 Feb 2008 18:17:35 -0500, Robert Morley wrote:

> I'm nowhere near writing my own Delphi DLLs for VB6 yet, but just for
> clarification, does "stdcall" create COM-compatible calls
> (MyDll.MyFunction), or do you have to use API-style declarations (Public
> Declare MyFunction "MyDll"...) in VB6?

These are global functions exported by a dll. If you want COM then you
need to create a COM server and implement interfaces instead of global
functions.

--
Marc Rohloff [TeamB]
marc -at- marc rohloff -dot- com

0 new messages