Board index » delphi » Passing strings from Delphi Dll

Passing strings from Delphi Dll

Hello,

I am trying to write a simple ActiveX dll in Delphi 7 that will be called
from a Visual Basic application.  I can return numerical values from this
component, but when it comes to strings, I am stumped.  I know that I am
supposed to use delphi's WideString as a return type, but the following vb
code locks up my process:

dim e as Eval
set e = new Eval

debug.print e.Test  '<----- locks here

Could someone PLEASE take a look at my Delphi code and tell me what I am
doing wrong?  It seems SO simple, and I was able to create a standard
library by passing PChar's, but VB does not let me call a function that
returns a PChar.  Any help would be greatly appriciated.

Dave
----------------------

library EvalX;

uses
  ComServ,
  EvalX_TLB in 'EvalX_TLB.pas',
  Unit1 in 'Unit1.pas' {Eval: CoClass};

exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;

{$R *.TLB}

{$R *.RES}

begin
end.

unit EvalX_TLB;

// ************************************************************************
//
// WARNING
// -------
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ************************************************************************
//

// PASTLWTR : 1.2
// File generated on 5/10/2003 6:45:17 PM from Type Library described below.

// ************************************************************************
//
// Type Lib: C:\DelphiProjects\EvalXDll8\EvalX.tlb (1)
// LIBID: {492CD19E-B795-4AF4-ACAA-B76A79CBEEE6}
// LCID: 0
// Helpfile:
// HelpString: EvalX Library
// DepndLst:
//   (1) v2.0 stdole, (C:\WINDOWS\System32\STDOLE2.TLB)
// ************************************************************************
//
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;

// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
//   Type Libraries     : LIBID_xxxx
//   CoClasses          : CLASS_xxxx
//   DISPInterfaces     : DIID_xxxx
//   Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
  // TypeLibrary Major and minor versions
  EvalXMajorVersion = 1;
  EvalXMinorVersion = 0;

  LIBID_EvalX: TGUID = '{492CD19E-B795-4AF4-ACAA-B76A79CBEEE6}';

  IID_IEval: TGUID = '{305E63C3-4C31-4260-900E-F61A3BCE3EAF}';
  CLASS_Eval: TGUID = '{7F1906AA-6524-487F-AE91-D878F55D2BB4}';
type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
  IEval = interface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
  Eval = IEval;

// *********************************************************************//
// Interface: IEval
// Flags:     (256) OleAutomation
// GUID:      {305E63C3-4C31-4260-900E-F61A3BCE3EAF}
// *********************************************************************//
  IEval = interface(IUnknown)
    ['{305E63C3-4C31-4260-900E-F61A3BCE3EAF}']
    function Test: WideString; stdcall;
  end;

// *********************************************************************//
// The Class CoEval provides a Create and CreateRemote method to
// create instances of the default interface IEval exposed by
// the CoClass Eval. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
  CoEval = class
    class function Create: IEval;
    class function CreateRemote(const MachineName: string): IEval;
  end;

implementation

uses ComObj;

class function CoEval.Create: IEval;
begin
  Result := CreateComObject(CLASS_Eval) as IEval;
end;

class function CoEval.CreateRemote(const MachineName: string): IEval;
begin
  Result := CreateRemoteComObject(MachineName, CLASS_Eval) as IEval;
end;

end.

unit Unit1;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, ActiveX, Classes, ComObj, EvalX_TLB, StdVcl;

type
  TEval = class(TTypedComObject, IEval)
  public
    function Test: WideString; stdcall;
  end;

implementation

uses ComServ;

function TEval.Test: WideString;
begin
  Result := WideString('Hello, World');
end;

initialization
  TTypedComObjectFactory.Create(ComServer, TEval, Class_Eval,
    ciMultiInstance, tmApartment);
end.

 

Re:Passing strings from Delphi Dll


Quote
> I am trying to write a simple ActiveX dll in Delphi 7 that will be called
> from a Visual Basic application.  I can return numerical values from this
> component, but when it comes to strings, I am stumped.  I know that I am
> supposed to use delphi's WideString as a return type...

Say what? You should use OleVariant for anything that's going to be read
into a VB app; it's the only thing VB really understands. (And that only
just barely...)

Quote
> the following vb
> code locks up my process:

> dim e as Eval
> set e = new Eval

> debug.print e.Test  '<----- locks here
> Could someone PLEASE take a look at my Delphi code and tell me what I am
> doing wrong?

<snip>

Quote
> type
>   TEval = class(TTypedComObject, IEval)
>   public
>     function Test: WideString; stdcall;
>   end;

In addition to OleVariants, try using safecall instead of stdcall. Other
than that, I think you'll be OK... Of course, I could always be wrong!

John H. Hedges

Re:Passing strings from Delphi Dll


On Sat, 10 May 2003 21:55:29 -0500, "J. Hedges"

Quote
<nobodyinparticu...@jh3.com> wrote:
>Say what? You should use OleVariant for anything that's going to be read
>into a VB app; it's the only thing VB really understands. (And that only
>just barely...)

I have never messed arounf with making AX DLLs in Delphi
However I have (reluctantly) done a few OCXes

Here is a snippet from one

function TEHTML_.Get_DefPreFontName: WideString;
begin
  Result := WideString(FDelphiControl.DefPreFontName);
end;

Variants are handy (in 'real' DLLs) for passing in/out strings of
indeterminate length

I think your bit about SafeCall rather than StdCall hit the nail on
the head

To the OP, I generally write 'real' DLLs in Delphi and provide a VB
Class to 'front' them
- perhaps because the AX stuff disgusts me

Re:Passing strings from Delphi Dll


Thank you both. After changing Safe Call Function Mapping to 'All v-table
interfaces', and Language from IDL to Pascal, I was able to get a
WideString: safecall function to 'stick' in my Delphi generated type
library.  Now ever thing works great!  Thanks again!

Dave

Quote
"J French" <Bounce_It_je...@iss.u-net.com_.bin> wrote in message

news:3ebdeafa.1976604@news.u-net.com...
Quote
> On Sat, 10 May 2003 21:55:29 -0500, "J. Hedges"
> <nobodyinparticu...@jh3.com> wrote:

> >Say what? You should use OleVariant for anything that's going to be read
> >into a VB app; it's the only thing VB really understands. (And that only
> >just barely...)

> I have never messed arounf with making AX DLLs in Delphi
> However I have (reluctantly) done a few OCXes

> Here is a snippet from one

> function TEHTML_.Get_DefPreFontName: WideString;
> begin
>   Result := WideString(FDelphiControl.DefPreFontName);
> end;

> Variants are handy (in 'real' DLLs) for passing in/out strings of
> indeterminate length

> I think your bit about SafeCall rather than StdCall hit the nail on
> the head

> To the OP, I generally write 'real' DLLs in Delphi and provide a VB
> Class to 'front' them
> - perhaps because the AX stuff disgusts me

Other Threads