Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Access classes in .bpl through a dll


This question is answered.


Permlink Replies: 6 - Last Post: May 16, 2016 4:15 PM Last Post By: Ian Johnson
Ian Johnson

Posts: 43
Registered: 3/14/06
Access classes in .bpl through a dll  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 8, 2016 11:02 PM
Hello,

I've been searching for information about classes, packages and dlls and am coming to the conclusion that it's all pretty tricky... Anyway, I'd be very grateful if anyone can point me in the right direction.

I've written a fairly large mathematical model in a package:

IJModel.bpl

This 'contains':

Modules - a folder with various individual files with classes in them
IJSim.pas - a file which has the main model class, TIJSim, that accesses the various classes in the 'Modules' folder

So, what I'd like to do is be able to write a dll that can create and access the TIJSim class defined in IJSim.pas, and then access the various methods.

I've worked through the very basic type of dll with a function to add a couple of numbers with this in the dll:

function AddNumbers(i1, i2: integer): integer; stdcall; export;
begin
result := i1 + i2;
end;

exports
AddNumbers;

This all works fine with this declaration in a form:

function AddNumbers(i1, i2: integer): integer; stdcall external 'DLL_test.dll';

Where I'm stuck is being able to create the TIJSim class in the form via a dll. The aim is to allow others to access this class from other languages which, itself, may be a whole other world of problems...

I'm presuming that there is something in the dll like this:

function Create_IJsim: TIJsim; stdcall; export;
begin
result := TIJsim.create;
end;

procedure Destroy_IJsim( IJSim: TIJsim); stdcall; export;
begin
IJSim.destroy;
end;

and then other procedures and functions for the various methods and properties of the class TIJsim.

Any help or suggestions greatly appreciated.

Thanks, Ian

Edited by: Ian Johnson on May 8, 2016 11:03 PM
Lajos Juhasz

Posts: 801
Registered: 3/14/14
Re: Access classes in .bpl through a dll [Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 9, 2016 7:43 AM   in response to: Ian Johnson in response to: Ian Johnson
Ian Johnson wrote:

Where I'm stuck is being able to create the TIJSim class in the form
via a dll. The aim is to allow others to access this class from
other languages which, itself, may be a whole other world of
problems...

I'm presuming that there is something in the dll like this:

function Create_IJsim: TIJsim; stdcall; export;
begin
result := TIJsim.create;
end;

procedure Destroy_IJsim( IJSim: TIJsim); stdcall; export;
begin
IJSim.destroy;
end;

and then other procedures and functions for the various methods and
properties of the class TIJsim.

Any help or suggestions greatly appreciated.

Thanks, Ian

You can return in your function a pointer or an integer value that
represents your objects. A pointer type can be easier to implement but
you would have no control to validate it in procedure calls.

I wold in the create procedure insert the object into a TObjectList (or
a generic list) and return the index of the objects. The first
parameter in the helpers functions would ask an integer the index for
the objects followed with any aditional parameters of the method:

function Create_IJsim: integer; stdcall;  
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim.create;
   result := myList.Add(lIjSim);
 end;
 
procedure Destroy_IJsim( IJSim: integer); stdcall; 
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim(myList[IJsim]);
 
   lIJSim.destroy;
   myList[IJsim]:=nil;
 end;
 
 
procedure DoSomething_IJsim(IJsim: integer; Param1, param2,.....);
var lIjSim: TIJsim;
begin
  lIjSim:=TIJsim(myList[IJsim]);
  lIjSim.Dosomething(Param1, Param2, ....)

Of course in the final code you should guard against invalid indexes!
Note do not raise any exception when the parameters are invalid....

Ian Johnson

Posts: 43
Registered: 3/14/06
Re: Access classes in .bpl through a dll [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 10, 2016 5:20 AM   in response to: Lajos Juhasz in response to: Lajos Juhasz
Lajos Juhasz wrote:
Ian Johnson wrote:

Where I'm stuck is being able to create the TIJSim class in the form
via a dll. The aim is to allow others to access this class from
other languages which, itself, may be a whole other world of
problems...

I'm presuming that there is something in the dll like this:

function Create_IJsim: TIJsim; stdcall; export;
begin
result := TIJsim.create;
end;

procedure Destroy_IJsim( IJSim: TIJsim); stdcall; export;
begin
IJSim.destroy;
end;

and then other procedures and functions for the various methods and
properties of the class TIJsim.

Any help or suggestions greatly appreciated.

Thanks, Ian

You can return in your function a pointer or an integer value that
represents your objects. A pointer type can be easier to implement but
you would have no control to validate it in procedure calls.

I wold in the create procedure insert the object into a TObjectList (or
a generic list) and return the index of the objects. The first
parameter in the helpers functions would ask an integer the index for
the objects followed with any aditional parameters of the method:

function Create_IJsim: integer; stdcall;  
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim.create;
   result := myList.Add(lIjSim);
 end;
 
procedure Destroy_IJsim( IJSim: integer); stdcall; 
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim(myList[IJsim]);
 
   lIJSim.destroy;
   myList[IJsim]:=nil;
 end;
 
 
procedure DoSomething_IJsim(IJsim: integer; Param1, param2,.....);
var lIjSim: TIJsim;
begin
  lIjSim:=TIJsim(myList[IJsim]);
  lIjSim.Dosomething(Param1, Param2, ....)

Of course in the final code you should guard against invalid indexes!
Note do not raise any exception when the parameters are invalid....


Thanks for the reply Lajos. I'm not sure I entirely follow. When I access the TIJsim class from another program, I want to be able to use all its methods and properties. Does this mean that the .dll has to have separate functions and procedures for all of them as well? Maybe it does.
Lajos Juhasz

Posts: 801
Registered: 3/14/14
Re: Access classes in .bpl through a dll [Edit]
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 10, 2016 6:14 AM   in response to: Ian Johnson in response to: Ian Johnson
Ian Johnson wrote:

Lajos Juhasz wrote:
Ian Johnson wrote:

Where I'm stuck is being able to create the TIJSim class in the
form via a dll. The aim is to allow others to access this class
from other languages which, itself, may be a whole other world of
problems...

I'm presuming that there is something in the dll like this:

function Create_IJsim: TIJsim; stdcall; export;
begin
result := TIJsim.create;
end;

procedure Destroy_IJsim( IJSim: TIJsim); stdcall; export;
begin
IJSim.destroy;
end;

and then other procedures and functions for the various methods
and properties of the class TIJsim.

Any help or suggestions greatly appreciated.

Thanks, Ian

You can return in your function a pointer or an integer value that
represents your objects. A pointer type can be easier to implement
but you would have no control to validate it in procedure calls.

I wold in the create procedure insert the object into a TObjectList
(or a generic list) and return the index of the objects. The first
parameter in the helpers functions would ask an integer the index
for the objects followed with any aditional parameters of the
method:

function Create_IJsim: integer; stdcall;  
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim.create;
   result := myList.Add(lIjSim);
 end;
 
procedure Destroy_IJsim( IJSim: integer); stdcall; 
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim(myList[IJsim]);
 
   lIJSim.destroy;
   myList[IJsim]:=nil;
 end;
 
 
procedure DoSomething_IJsim(IJsim: integer; Param1, param2,.....);
var lIjSim: TIJsim;
begin
  lIjSim:=TIJsim(myList[IJsim]);
  lIjSim.Dosomething(Param1, Param2, ....)

Of course in the final code you should guard against invalid
indexes! Note do not raise any exception when the parameters are
invalid....


Thanks for the reply Lajos. I'm not sure I entirely follow. When I
access the TIJsim class from another program, I want to be able to
use all its methods and properties. Does this mean that the .dll has
to have separate functions and procedures for all of them as well?
Maybe it does.

Of course it would required to introduce a function/procedure for
everything accessable through DLL.

Other language and even Delphi without the dcu has no information about
your objects. You can find an article how to flatten a C++ class using
a DLL: http://rvelthuis.de/articles/articles-cppobjs.html#flattening.
Ian Johnson

Posts: 43
Registered: 3/14/06
Re: Access classes in .bpl through a dll [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 10, 2016 3:44 PM   in response to: Lajos Juhasz in response to: Lajos Juhasz
Lajos Juhasz wrote:
Ian Johnson wrote:

Lajos Juhasz wrote:
Ian Johnson wrote:

Where I'm stuck is being able to create the TIJSim class in the
form via a dll. The aim is to allow others to access this class
from other languages which, itself, may be a whole other world of
problems...

I'm presuming that there is something in the dll like this:

function Create_IJsim: TIJsim; stdcall; export;
begin
result := TIJsim.create;
end;

procedure Destroy_IJsim( IJSim: TIJsim); stdcall; export;
begin
IJSim.destroy;
end;

and then other procedures and functions for the various methods
and properties of the class TIJsim.

Any help or suggestions greatly appreciated.

Thanks, Ian

You can return in your function a pointer or an integer value that
represents your objects. A pointer type can be easier to implement
but you would have no control to validate it in procedure calls.

I wold in the create procedure insert the object into a TObjectList
(or a generic list) and return the index of the objects. The first
parameter in the helpers functions would ask an integer the index
for the objects followed with any aditional parameters of the
method:

function Create_IJsim: integer; stdcall;  
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim.create;
   result := myList.Add(lIjSim);
 end;
 
procedure Destroy_IJsim( IJSim: integer); stdcall; 
var lIjSim: TIJsim;
 begin
   lIjSim:=TIJsim(myList[IJsim]);
 
   lIJSim.destroy;
   myList[IJsim]:=nil;
 end;
 
 
procedure DoSomething_IJsim(IJsim: integer; Param1, param2,.....);
var lIjSim: TIJsim;
begin
  lIjSim:=TIJsim(myList[IJsim]);
  lIjSim.Dosomething(Param1, Param2, ....)

Of course in the final code you should guard against invalid
indexes! Note do not raise any exception when the parameters are
invalid....


Thanks for the reply Lajos. I'm not sure I entirely follow. When I
access the TIJsim class from another program, I want to be able to
use all its methods and properties. Does this mean that the .dll has
to have separate functions and procedures for all of them as well?
Maybe it does.

Of course it would required to introduce a function/procedure for
everything accessable through DLL.

Other language and even Delphi without the dcu has no information about
your objects. You can find an article how to flatten a C++ class using
a DLL: http://rvelthuis.de/articles/articles-cppobjs.html#flattening.

Thanks Lajos - that make sense. I appreciate your help.
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Access classes in .bpl through a dll [Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 11, 2016 10:48 AM   in response to: Ian Johnson in response to: Ian Johnson
Ian Johnson wrote:

Hello,

I've been searching for information about classes, packages and dlls
and am coming to the conclusion that it's all pretty tricky...
Anyway, I'd be very grateful if anyone can point me in the right
direction.

I've written a fairly large mathematical model in a package:

IJModel.bpl

This 'contains':

Modules - a folder with various individual files with classes in them
IJSim.pas - a file which has the main model class, TIJSim, that
accesses the various classes in the 'Modules' folder

So, what I'd like to do is be able to write a dll that can create and
access the TIJSim class defined in IJSim.pas, and then access the
various methods.

I've worked through the very basic type of dll with a function to add
a couple of numbers with this in the dll:

function AddNumbers(i1, i2: integer): integer; stdcall; export;
begin
result := i1 + i2;
end;

exports
AddNumbers;

This all works fine with this declaration in a form:

function AddNumbers(i1, i2: integer): integer; stdcall external
'DLL_test.dll';

Where I'm stuck is being able to create the TIJSim class in the form
via a dll. The aim is to allow others to access this class from
other languages which, itself, may be a whole other world of
problems...

No chance, you have to wrap the class into a COM class wrapper and
export that if you want it to be usable from another language.
Otherwise there is no way how you can explain to the other language
code what your class is able to do, how to call its methods, what
method it has, and so on. To be able to use the package this way is
only possible from Delphi code that has been build with run-time
packages and has this package in its used packages list. Packages are
Delphi-specific (ok C++ Builder can also use them) and they are even
specific to a certain Delphi version.


I'm presuming that there is something in the dll like this:

function Create_IJsim: TIJsim; stdcall; export;

The caller would not know the TIJsim type and be unable to use the
returned reference in any useful way. You can of course write a set of
exported functions, one for each method of the class you want to be
accessible, but that would be painful to use. COM is more generally
useful and guarantees that all parameter types you use are in fact
compatible with the caller's expectations.

--
Peter Below
TeamB

Ian Johnson

Posts: 43
Registered: 3/14/06
Re: Access classes in .bpl through a dll [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 16, 2016 4:15 PM   in response to: Peter Below in response to: Peter Below
Peter Below wrote:
Ian Johnson wrote:

Hello,

I've been searching for information about classes, packages and dlls
and am coming to the conclusion that it's all pretty tricky...
Anyway, I'd be very grateful if anyone can point me in the right
direction.

I've written a fairly large mathematical model in a package:

IJModel.bpl

This 'contains':

Modules - a folder with various individual files with classes in them
IJSim.pas - a file which has the main model class, TIJSim, that
accesses the various classes in the 'Modules' folder

So, what I'd like to do is be able to write a dll that can create and
access the TIJSim class defined in IJSim.pas, and then access the
various methods.

I've worked through the very basic type of dll with a function to add
a couple of numbers with this in the dll:

function AddNumbers(i1, i2: integer): integer; stdcall; export;
begin
result := i1 + i2;
end;

exports
AddNumbers;

This all works fine with this declaration in a form:

function AddNumbers(i1, i2: integer): integer; stdcall external
'DLL_test.dll';

Where I'm stuck is being able to create the TIJSim class in the form
via a dll. The aim is to allow others to access this class from
other languages which, itself, may be a whole other world of
problems...

No chance, you have to wrap the class into a COM class wrapper and
export that if you want it to be usable from another language.
Otherwise there is no way how you can explain to the other language
code what your class is able to do, how to call its methods, what
method it has, and so on. To be able to use the package this way is
only possible from Delphi code that has been build with run-time
packages and has this package in its used packages list. Packages are
Delphi-specific (ok C++ Builder can also use them) and they are even
specific to a certain Delphi version.


I'm presuming that there is something in the dll like this:

function Create_IJsim: TIJsim; stdcall; export;

The caller would not know the TIJsim type and be unable to use the
returned reference in any useful way. You can of course write a set of
exported functions, one for each method of the class you want to be
accessible, but that would be painful to use. COM is more generally
useful and guarantees that all parameter types you use are in fact
compatible with the caller's expectations.

--
Peter Below
TeamB


Thanks Peter (apologies for a delay in responding). I can see there is a bit in this!

Ian
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02