0

I have have a DLL that creates a connection object to a database. This is part of the code of the function:

AADConnection = ^TADConnection;

......

function OpenPGConnection: Pointer; register;
var
  RC: Integer;
  ERRM: String;
  ADConnection: TADConnection;
  P: AADConnection;
begin
  New(P);
  P^:= TADConnection.Create(nil);
  P^.Name:= 'ADConnection123';
  P^.FetchOptions.Unidirectional:= True;
  .....
  Result:= Pointer(P);
end;

This is how I use this function:

function OpenPGConnection: Pointer; register; external 'mypqconnection.dll';

......

var
  P: AADConnection;

.....

begin 
  P:= OpenPGConnection;
  ADConnection:= P^;
  ShowMessage(ADConnection.Name); 
  if ADConnection.connected  then ShowMessage('True') else 
    ShowMessage('False');  

.....

  Q.Connection:= ADConnection;
  Q.Close;
  Q.SQL.Clear;
  Q.SQL.Add('select * from mytable');
  Q.Open;

ShowMessage(ADConnection.Name) gives the right name "ADConnection123" and check for connectivity returns "True". But when I run Q.Open then I get "Invalid Class Typecast". I know returning pointer to object from a DLL is very tricky business but at first glance it seems this code returns the correct values. Still something is not right. What can it be?

EDIT: I have tried the suggested solutions from these two topics:

Putting classes in a DLL?

Accessing classes that are in another DLL?

Fist I rewrote the DLL and the main program using Interface. Then I tried runtime BPL package. I always got 'Invalid Class Typecast'.

Georgi Bonchev
  • 269
  • 4
  • 12
  • 3
    The only way I can see this working is if TADConnection resides in a runtime package that both the exe and dll refers to. And even then, I would not recommend it. The thing is, if you build without runtime package, the DLL and the EXE will each have their own copy of the class and while they might end up binary compatible, they will have different class reference. For this reason, the IS operator will fail, amongst other things. (ADConnection.ClassType <> TADConnection). – Ken Bourassa Aug 20 '19 at 13:23
  • 2
    Class X compiled into your application is different from class X compiled into the DLL (same code, two different copies in two different modules). As a consequence, `is` and `as` operators will fail (even for `TObject`). The only reliable way is to use runtime packages, abstract classes or interfaces. – Ondrej Kelle Aug 20 '19 at 13:25

0 Answers0