Board index » delphi » Re: Problem with plugin in DLL

Re: Problem with plugin in DLL


2005-11-21 04:57:30 AM
delphi49
Quote
No, I thought to use variables with common classes you needed to use
the runtime libs
Maybe I am misunderstanding what you are saying, but if this were true, you
would not be able to call someone elses DLL.
 
 

Re: Problem with plugin in DLL

Quote
>I think it depends a bit on the variables/classes involved.
Correct, but I do agree with everything else about using Runtimes. He could
also use something Hydra to make it easier for him.
 

Re: Problem with plugin in DLL

Liz writes:
Quote

No, I thought to use variables with common classes you needed to use
the runtime libs
Ah, now I know what you meant. Of course all global variables
(Application, Screen, ..) in the dll's version of the RTL/VCL need to be
'tweaked' to contain the 'correct' values. *g*
Sharemem is another topic, yes.
Willi
 

Re: Problem with plugin in DLL

"Eugene V. Goldberg" <XXXX@XXXXX.COM>writes
Quote
if you dont want to use runtime libs, you can try to patch Graphics.pas
and rebuild your DLL:

procedure TFont.Assign(Source: TPersistent);
begin
//if Source is TFont then
//begin
Ouch!
No, please don't.
The whole assign mechanism depends on each piece being
able to recognize which objects it can handle.
Your patch will call TFont(Source).PixelsPerInch on any
object passed in, even if it is not a TFont.
This takes the offset of PixelsPerInch in TFont and reaches
into Source and grabs the data at that offset.
Even worse is Size. It finds the offset of GetSize and executes
whatever code is at that offset in Source.
This is fine if Source *happens* to be a TFont. But since
your code is telling you that the two versions don't match
up, you are playing with fire.
It is perfectly legal to call assign on any object knowing
that it will only assign what it can. You have broken that
guarantee.
This is just a time bomb waiting to go off in ways that
you won't recognize as related.
--
Brad.
 

Re: Problem with plugin in DLL

Brad White writes:
Quote
"Eugene V. Goldberg" <XXXX@XXXXX.COM>writes
news:4380676e$XXXX@XXXXX.COM...
>if you dont want to use runtime libs, you can try to patch
>Graphics.pas and rebuild your DLL:
>
>procedure TFont.Assign(Source: TPersistent);
>begin
>//if Source is TFont then
>//begin


Ouch!

No, please don't.
The whole assign mechanism depends on each piece being
able to recognize which objects it can handle.
Your patch will call TFont(Source).PixelsPerInch on any
object passed in, even if it is not a TFont.
This takes the offset of PixelsPerInch in TFont and reaches
into Source and grabs the data at that offset.
Even worse is Size. It finds the offset of GetSize and executes
whatever code is at that offset in Source.
This is fine if Source happens to be a TFont. But since
your code is telling you that the two versions don't match
up, you are playing with fire.
It is perfectly legal to call assign on any object knowing
that it will only assign what it can. You have broken that
guarantee.
This is just a time bomb waiting to go off in ways that
you won't recognize as related.
Search for my name (Joe Bain) and IsClassInstance in
b.p.d.lang.delphi.general and you will find a safe way for testing if
it is the correct TFont before assigning.
--------------
Joe Bain
www.iegsoftware.com
 

Re: Problem with plugin in DLL

Joe Bain writes:
Quote
Search for my name (Joe Bain) and IsClassInstance in
b.p.d.lang.delphi.general and you will find a safe way for testing if
it is the correct TFont before assigning.
I should note that I ended up using packages instead.
--------------
Joe Bain
www.iegsoftware.com
 

Re: Problem with plugin in DLL

Sorry, maybe I dont understand everything you have said, but I have
problem. I remade my dll into packages, but I cant load more than one
package. When Im trying load others it causes a exception saying that I
cant load plugin.pas because the first package has already loaded
plugin.pas before. I dont know what Im doing wrong :(
BTW in plugin.pas is the base class of my all plugins, so I must use it in
my packages...
Thanks for helping to lama :)
On Sun, 20 Nov 2005 16:36:29 +0100, Willi Krenn <XXXX@XXXXX.COM>
writes:
Quote
Jirka,

>I have little application and I want make plugins for it. I have made
>TPlugin class(TScrollBox) and each plugin should be in DLL. But it
>doesn't do what it should. It raises this message: "canno assign a
>tfont to a tfont".
>In DLL i have a function that returns instance of TPlugin. But when I
>assign parent of TPlugin then I receive message: "canno assign a tfont
>to a tfont". Where is the problem??

As Liz already said: Use runtime libraries! Compile the application and
the dll with runtime packages enabled. ('vcl' should be enough IMO)
And while you're at it, I'd highly recommend switching from '.dll'
to 'package' plugins: It gives you better de{*word*81} support in the IDE
and a far better integration in the main application.
Internally, the .bpl file is still a dll-file, but the delphi compiler
will provide mangled function names (for overloading), and various
entrypoints for typeinfo, global vars etc. (Of course you can add your
own entrypoints too.)

That being said, it is possible to patch the RTL/VCL in a way so you can
even have working forms in a dll (including hint windows, menus etc) - I
did this for D5 -, but it is not worth the effort.

BTW: When not using runtime packages, each of your plugins will include
an "almost full" copy of the RTL/VCL...

HTH
Willi
--
Using Opera's revolutionary e-mail client: www.opera.com/mail/
 

Re: Problem with plugin in DLL

Jirka,
Quote
Sorry, maybe I dont understand everything you have said, but I have
problem. I remade my dll into packages, but I cant load more than one
package. When Im trying load others it causes a exception saying that I
cant load plugin.pas because the first package has already loaded
plugin.pas before. I dont know what Im doing wrong :(
Well, it is pretty simple: Each unit may only be included once in a .exe
file and it is .bpl files. This is quite logically, because if a unit -
that might have e.g. global variables - was linked more than once into
your application, you'd have more than one copy of your unit resulting
in more than one of the -possibly included- global variables. You'd have
a hard time figuring out which of all these global variables were the
'correct' ones.. The Delphi compiler knows about this problem and does
not allow multiple inclusion of a unit. (With some exceptions IIRC.)
To solve your problem you have to change your plugin-architecture a
little bit by introducing another package. (See below)
Quote
BTW in plugin.pas is the base class of my all plugins, so I must use it
in my packages...
To solve your problem, create a package that contains all the basic
stuff you need for your plugin system to work: All basic types your
plugins later on are derived from, perhaps some code that scans a
directory looking for loadable plugins (packages) etc.. Take this stuff
and put it in a package - I will call it 'PluginBasics' for now.
Your application module layout should now look something like:
<Main.Exe>
| |
<??><PluginBasics.Bpl>
| |
<VclXY.Bpl><WhateverYouNeed.Bpl>
The "Main.Exe" module can use the routines contained in 'PluginBasics'
for triggering loading of plugins at runtime and will probably also use
the typedefinitions in one of the units (e.g. plugin.pas) from
'PluginBasics'.
Next, you create a real plugin package that uses the types contained in
pluginbasics.bpl as a basis and derives new funtionality from it; Let's
call this package 'Plugin1' for now:
<Plugin1.Bpl>
|
<PluginBasics.Bpl>
|
<VclXY.Bpl>
Sticking everything together (we finally load the plugin), we get:
<Main.Exe><Plugin1.Bpl>
| |
<PluginBasics.Bpl>
|
<VclXY.Bpl>
With little planing you can figure out a unit-distribution so each unit
is linked only once into the whole project (.exe plus all .bpls you load).
HTH
Willi