Hi,
OS: Windows NT & Windows 2000
D?: Delphi 5 Enterprise
Now I know... the subject seems a bit strange, I'll explain.
My application will be calling a dll-function, where it passes an
Integer(MyObj) as a var.
By using memory mapped files (Thanks to Marco Cantu in 'Mastering Delphi6',
chapter 12, page 506) I can gain access to the actual object passes to the
function. This is where the problem starts. The object contains strings x,
y, z. When passing the object, x and y are set to something... no prob. Even
inside the dll, after getting the object I can actually read the x and y
vars. Inside the dll I state that z := x + y. Nothing special I should
say???
After returning to the application, z is no longer available, and I get an
exception when I try to access it like ShowMessage(MyObj.z).
To explain a bit further:
---- The object being
passed... ------------------------------------------------------------------
-------------------------------
type
TMyObj = class
x,
y,
z : string;
end;
---- The function inside the
dll... ---------------------------------------------------------------------
-----------------
function RUN_External(aCommand, aResult : PChar; Context : integer) :
integer; stdcall;
var
p : string;
hMapFile : THandle;
ShareData: ^TMyObj;
const
VirtualFileName = 'ShareDllData';
DataSize = SizeOf(TMyObj);
begin
Result := 0;
//create memory mapped file
hMapFile := CreateFileMapping($FFFFFFFF, nil, Page_ReadWrite, 0, DataSize,
VirtualFileName);
if hMapFile =0 then
raise Exception.Create('Error creating memory-mapped file');
//get the pointer to the actual data
ShareData := MapViewOfFile(hMapFile, File_Map_Write, 0, 0, DataSize);
if Context <> 0 then begin
ShareData^ := TMyObj(Context);
ShareData^.z := ShareData^.x + ShareData^.y; <<<<<<<<<<<----------- it
should be complaining here by now... but it doesn't... and x and y are
definalty set...
end;
case CommandType(aCommand) of
ctQuery : case QueryType(aCommand) of
qtConcept : p := 'Query Concept';
qtConvert : p := 'Query Convert';
qtDetails : p := 'Query Concept';
qtSummary : p := 'Query Concept';
else begin
p := 'Unknown request';
Result := -1;
end; //begin
end; //case
ctTrans : case TransType(aCommand) of
ttFAX : p := 'Trans FAX';
ttSMS : p := 'Trans SMS';
else begin
p := 'Unknown transaction';
Result := -1;
end; //begin
end; //case
else begin
p := 'Unknown Command' + ShareData^.z;
Result := -1;
end; //begin
end; //case
UnmapViewOfFile(ShareData);
CloseHandle(hMapFile);
StrCopy(aResult, PChar(p));
end;
---- Finally, the code inside the
form... --------------------------------------------------------------------
----------
function ExecuteExternalFunction(Input : string; var Output : string;
Context : integer) : integer;
const
Run_External_Name = 'RUN_External';
DLLFile = 'External.dll';
var
DLLHandle : THandle;
RUN_External : function(aCommand, aResult : PChar; Context : integer) :
integer; stdcall;
s : string;
begin
DLLHandle := LoadLibrary(DLLFile);
Assert(DLLHandle >= 32);
@Run_External := GetProcAddress(DLLHandle, PChar(Run_External_Name));
Assert(@Run_External <> nil);
SetLength(s, 2048);
Result := RUN_External(PChar(Input), PChar(s), Context);
Output := PChar(s);
FreeLibrary(DLLHandle);
end;
procedure TMainForm.bCallClick(Sender: TObject);
var
s, t : string;
i : integer;
O : TMyObj;
begin
s := rgCommand.Items[rgCommand.ItemIndex] + #20;
case rgCommand.ItemIndex of
0 : s := s + rgQuery.Items[rgQuery.ItemIndex] + #20;
1 : s := s + rgTrans.Items[rgTrans.ItemIndex] + #20;
end;
O := TMyObj.Create;
try
O.x := 'X';
O.y := 'Y';
i := ExecuteExternalFunction(s, t, Integer(O));
ShowMessage(IntToStr(i) + #13 + t + #13 +
O.x + #13 + O.y + #13 + O.z);
<<<<<<<------------ this is where I get an exception... z is no longer
available here...
finally
O.Free;
end;
end;
----------------------------------------------------------------------------
----------------------------------------
What I do know, is when I remove all stuff for the object, I have the
correct code to pass STRINGS from EXE to DLL and BACK!!!
This took a while to figure out. I don't want to rely on borlandmm.dll hehe
In the end the question comes to this:
How do I get ANY object from exe to dll, modify it, and pass it back to exe?
Thanks,
Rory Vieira
GIOS Voice Professionals
Network Manager / Developer
rory dot vieira at gios dot nl