Discussion:
Making plugin system with shared libraries. Upcast in shared lib
MrSmith via Digitalmars-d-learn
2014-10-19 22:32:14 UTC
Permalink
I'm using Windows.

I was making some sort of modular system where you can define
modules that are loaded by host application.
Here is a simple example
https://gist.github.com/MrSmith33/7692328455a19e820a7c
Now i want to separate these "modules" in separate shared libs
and link them on the fly.
The issue i have is that some modules can define some useful
functions and in order to use them you need to upcast to concrete
type. This is easy in a single application, but i was unable to
do this through dll boundary.

So basically all dll's have factory function that returns an
instance of IModule.
Than any module can search for registered modules and try to cast
them to concrete type (upcast).

in imodule.d

interface IModule
{
string name();
void init(ModuleManager modman);
}

in module1.d (dll)

class Module1 : IModule
{
override string name() {return "Module1";}

override void init(ModuleManager modman)
{
IModule module2 = modman.findModule("Module2");
if (auto m = cast(Module2)module2)
{
m.someMethod2();
}
}
}

in module2.dll (dll)

class Module2 : IModule
{
override string name() {return "Module2";}
override void init(ModuleManager modman){}
void someMethod2(){}
}

And what files should i compile with what packages?
application
IModule
main
other

module1 dll
IModule
Module1
Module2 - should i import it, compile of import .di file?

module2 dll
IModule
Module2

Is it possible at all? Or it is an issue with Windows shared lib
support?
Kagamin via Digitalmars-d-learn
2014-10-20 14:05:28 UTC
Permalink
Do it the COM way: publish IModule2 interface and declare
GetInterface method, which will return a prepared pointer, which
you would reinterpret cast to IModule2.
MrSmith via Digitalmars-d-learn
2014-10-20 15:07:41 UTC
Permalink
Post by Kagamin via Digitalmars-d-learn
Do it the COM way: publish IModule2 interface and declare
GetInterface method, which will return a prepared pointer,
which you would reinterpret cast to IModule2.
Will it work on linux with simple .so libs?
I want it to be as simple as possible.
Kagamin via Digitalmars-d-learn
2014-10-21 13:57:21 UTC
Permalink
Post by MrSmith via Digitalmars-d-learn
Post by Kagamin via Digitalmars-d-learn
Do it the COM way: publish IModule2 interface and declare
GetInterface method, which will return a prepared pointer,
which you would reinterpret cast to IModule2.
Will it work on linux with simple .so libs?
I want it to be as simple as possible.
Is it any different from what you already have?
Dynamic cast is not guaranteed to work across dll boundary. If it
does, you're lucky. If it doesn't, use GetInterface - that will
work independently from runtime, environment, language, os,
hardware etc.
MrSmith via Digitalmars-d-learn
2014-10-21 21:50:53 UTC
Permalink
Post by Kagamin via Digitalmars-d-learn
Post by MrSmith via Digitalmars-d-learn
Post by Kagamin via Digitalmars-d-learn
Do it the COM way: publish IModule2 interface and declare
GetInterface method, which will return a prepared pointer,
which you would reinterpret cast to IModule2.
Will it work on linux with simple .so libs?
I want it to be as simple as possible.
Is it any different from what you already have?
Dynamic cast is not guaranteed to work across dll boundary. If
it does, you're lucky. If it doesn't, use GetInterface - that
will work independently from runtime, environment, language,
os, hardware etc.
What is GetInterface?
Kagamin via Digitalmars-d-learn
2014-10-22 07:45:43 UTC
Permalink
It's how COM casts objects
http://msdn.microsoft.com/en-us/library/ms687230.aspx
Kagamin via Digitalmars-d-learn
2014-10-22 07:49:23 UTC
Permalink
The idea is that the object you work with is responsible for
casting itself to an interface you need.

Martin Nowak via Digitalmars-d-learn
2014-10-20 15:30:20 UTC
Permalink
Than any module can search for registered modules and try to cast them
to concrete type (upcast).
That can't work because the notion of types only exists during
compilation. Therefor it's not possible to load new types at runtime and
use them in code that was compiled without knowing those types.
You should simply use interfaces to achieve your goal.
MrSmith via Digitalmars-d-learn
2014-10-20 18:29:42 UTC
Permalink
Post by Martin Nowak via Digitalmars-d-learn
Post by MrSmith via Digitalmars-d-learn
Than any module can search for registered modules and try to
cast them
to concrete type (upcast).
That can't work because the notion of types only exists during
compilation. Therefor it's not possible to load new types at
runtime and use them in code that was compiled without knowing
those types.
You should simply use interfaces to achieve your goal.
In this case ether shared lib knows actual type.

But i've tried it with interfaces, (upcast also), or do you mean
something else?

1) I want application to load IModule from .so/.dll
2) Any other module should be able to cast that IModule to actual
type (upcast) and test if result is !null.
3) Can i do this using interfaces or without them? I.e. if in
first example module2 is interface
Loading...