Running a Delphi 7.0-made DLL in an MSOffice macro.

Good afternoon or other relevant time period, Experts.

I have created a DLL in Delphi 7, within which I have a single external function with the following 4 lines of code
Form1 := form1.create(application);
Form1.ShowModal;
Result := PChar(Form1.StringVariable);
Form1.Free;

In Word I have created a macro to run the function, retreiving the value as a string, which then uses that string value to set the save directory. This works perfectly, but only once - any attempt to run the macro a second time withouteither restarting Word or going into VBA and resetting the macro will cause the DLL to crash after closing the screen (i.e. on setting the result). I have tried creating a test Delphi application to run the macro, which did not bump into this problem.

Any help would be much appreciated,
     SWOne

nB1: Trying to create a second function in the same DLL and running it through Word VBA, one with a PChar declared as a string didn't work at all (causing Word to crash), while one with an integer worked fine.

nB2: Not sure whther this belongs in Office, VB or Delphi. I'll try here first and see what response I get, then move on. Any suggestion on where it would be best asked would be appreciated.
LVL 2
SWOneAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ZhaawZSoftware DeveloperCommented:
could you show source of dll?
0
SWOneAuthor Commented:
Certainly...
library Project2;

uses
  SysUtils,
  Classes,
  Dialogs,
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

function SetCaseCode: pchar; stdcall;
var frm1: TForm1;
begin
  frm1 := TForm1.Create(Application);
  frm1.ShowModal;
  Result := pchar(frm1.CaseCode);
  frm1.free;
end;

exports SetCaseCode;


*******************************************************************

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB, ADODS, ActiveX;

type
  TForm1 = class(TForm)
    ADODatabase1: TADODatabase;
    ADODataSet1: TADODataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Edit1: TEdit;
    Button1: TButton;
    ADODataSet1CO_NAME: TStringField;
    ADODataSet1CODE: TStringField;
    ADODataSet1rowguid: TStringField;
    procedure Edit1Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    CaseCode: ansistring;
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}

procedure TForm1.Edit1Change(Sender: TObject);
begin
  ADODataset1.Close;
  ADODataset1.parambyname('CCode').asstring := '%'+trim(Edit1.Text)+'%';
  ADODataset1.Open;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CaseCode :=  ADODataSet1CODE.asstring;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caHide;
end;

initialization
  CoInitialize(nil); // <-- manually call CoInitialize()
finalization
  CoUnInitialize; // <-- free memory

end.
***********************************************************************************************
The form consists of a TEdit, and a DBGrid linked to a ADODatabase. As I said, it works fine in Delphi, and fine once in the macro. Just not twice.
0
SWOneAuthor Commented:
After a few hours work, I've managed to fix this myself. Using the code suggested in http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20396682.html?query=sharemem+vb&clearTAFilter=true , I've changed the function to  

function SetCode: pchar; stdcall;
var frm1: TForm1;
    LocalString:PChar;
    Len:Integer;
begin
  frm1 := TForm1.Create(Application);
  frm1.ShowModal;
  LocalString:=pchar(frm1.Code);
  Len:=StrLen(LocalString)+1;
  GetMem(Result,Len);
  StrMove(Result,LocalString,Len);
  frm1.free;
end;

and am getting no more errors.
0
GranModCommented:
Closed, 350 points refunded.
GranMod
The Experts Exchange
Community Support Moderator of all Ages
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.