[Qt-interest] dll problem

Evan Teran eteran at alum.rit.edu
Mon Dec 15 18:38:20 CET 2008


I think you have missed half of my desired functionality. There are two
parts.

#1. Have functions/classes which any plugin or the main application can
use. These are covered by the core library easily. Mostely a non-issue,
in fact it is only an inconvenience because of my initial plugin design
not having a "core library".

#2. I want plugins to be able to use functions and data found in the
main application. I believe you have overlooked this. Either that, or
you would have pretty much the entire application reside in a library.


>>> On 13.12.08 19:29:02, Evan Teran wrote:
>>>> I've done some basic tests and it all seems to work perfectly. The
>>>> plugins properly resolve the symbols which are provided by the plugin.
>>> That doesn't make it a good design.
>> Unfortunately, no one has really said *why* it isn't good design. Either
>> way the plugin has a dependency on the main application.
> 
> No it doesn't. With a core library you have a dependency on that library.
> The executable can be substituted in that case. 

If i need plugins to be able to call functions and use data provided by
the main application, then the plugins certainly *do* have a dependency
on the main application. One way or the other. And if the entire
application effectivly resides in a library itself. Then it's the same
difference, we're just calling it by a different name.

> 
>> The only real
>> difference is how the dependency is enforce. If you pass a structure of
>> function pointers, then it's enforced by the compiler. Otherwise it is
>> enforced by the linker. I find that there is no technical reason why an
>> application can't have exports which plugins can find useful. If it is
>> in fact bad design, what is the negative consequence?
> 
> One reason would be that it doesn't work on all platforms another would be
> that you need to jump through hoops to make this work on the single
> platform that does support it.
> 
> Maybe "good design" isn't quite the right wording, lets say the fact that
> it does work, doesn't make it less of a hack.

You have this a little backwards. From what I can tell, MSVC is the odd
one out in not having direct support for this. both Linux and OSX
targets seem to support this as far as I can tell.

As far as the "jump through hoops to make this work on the single
platform that does support it.", in the grand scheme of things adding
"-rdynamic" to my linker flags is hardly an obstacle of any kind. In
fact, it (being a single word added to a build file solution) is by far
one of the easiest solutions.


>>>> The main reason I am prefering this is that there are several "utility"
>>>> classes which most plugins use. So in the beginning I placed these in my
>>>> main apps sources and the plugins just used them. Now with the new
>>>> system because these classes need function definitions, I have to have a
>>>> "core library" which all plugins link to. I can either make it static
>>>> which makes the install just as simple as before but bloats the binary.
>>>> Or I have have it shared and have an even more complicated dependancy
>>>> tree with an extra library that has to be installed. If having the main
>>>> .exe provide these classes is workable, it is simpler.
>>> Thats a non-issue, because you ship .exe+.dll in the same directory on
>>> windows and use RPATH on *nix to make sure the right library is used.
>> Point well taken, I hadn't considered RPATH as an option and I will be
>> looking into that. However no matter how you cut it having an extra
>> "core library" does complicate my source tree. But in the grand scheme
>> of things that in itself is acceptable. So i'll concede this point.
> 
> I don't see how it would complicate the source tree, the files can
> still reside where they are now and simply be put into a different target
> than currently.

Fair enough, it doesn't have to complicate things.

>>>> Also, if the main app can export symbols, then that means I only have to
>>>> update 1 place to change my API, not several (as I do now with my new
>>>> plugin system).
>>> Thats simply wrong. If you change the existing API (rename
>>> classes/methods/functions or move stuff around) then you have to update
>>> _all_ places that are using the changed API. It doesn't make any difference
>>> wether the shared code is compiled into the .exe or into a shared library. 
>> I disagree. It is a given that the plugins would have to be updated to
>> use the new names/params of functions, in all places that use the API.
>> So that is immaterial, it happens no matter what the API scheme.
>> However, If I have a structure which has function pointers, then I have
>> to both update my API at an implementation level *and* update the
>> structure which has my function pointers.
> 
> Well, then why have function pointers in the first place? Last I checked
> C++ is pretty powerful without having to use function pointers, especially
> if you're using Qt. So far I haven't seen code that provides a plugin
> system and public API for the plugins to use/communicate with the "core" of
> the application that allows to update only the plugins and not the core
> application parts.

How do you propose I allow the application access to functions/data in
my main application without passing it function pointers? We've spent
some time discussing how using something like -rdynamic may not be a
good way to do it. Well if I don't give the plugin pointers to the
resouces they need...and the linker won't do it for me. How should it be
done?

The only real alternative I see is to have nearly all of the main
application provided by the "core library". To be honest, that feels WAY
more hacky than simply letting plugins touch certain parts of the main
application.

>> Also, my original scheme was an "always add" concept. My API had
>> namespaces like: "plugin::v1::functionName", once version 1.0 is
>> finalized, the "plugin::v1" namespace is permanent, no more changes to
>> it. The plan was to *never* remove something (calling it deprecated i
>> considered fair game though). Instead, as the API evolves I would add
>> "plugin::v2" namespaces and so on. The idea being that a plugin built
>> for version 1 of the API would always work. I realize that this also
>> could be done with a version variable in the structure. And always
>> adding on to the end of the structure. But with namespaces, it was just,
>> implicit.
> 
> Thats quite normal, but I don't see how that plays a role. If you never
> remove anything from the API, then the existing code will always work. If
> you introduce new API, you have to write the implementation for that new
> API as well as adjust any places that should use the new API. Wether you
> compile the API implementation into the executable, or into a core library
> that the executable links to doesn't make any difference here.

Agreed, I was just explaining how I wanted to organize things.

>> Plus a final point I forgot to mention earlier is that the function
>> pointer method has no support at all for function overloading.
> 
> I don't understand where function pointers come into the game. I'm just
> talking about compiling the code for the plugin system and the public API
> into a shared library and let the executable link against that. There are
> no function pointers involved with that. If you want an example, look at Qt
> Designer's source code, it has a core library which provides some of the
> functionality of the main application, allows for plugins to be used and
> the main application simply combines these by some API calls into a
> complete GUI.

Once again, having practically the entire application be found in a
library is just a workaround for the fact that something like -rdynamic
doesn't exist on MSVC. Now *that* feels like a hack to me.



More information about the Qt-interest-old mailing list