www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Making plugin system with shared libraries. Upcast in shared lib

reply "MrSmith" <mrsmith33 yandex.ru> writes:
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?
Oct 19 2014
next sibling parent reply "Kagamin" <spam here.lot> writes:
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.
Oct 20 2014
parent reply "MrSmith" <mrsmith33 yandex.ru> writes:
On Monday, 20 October 2014 at 14:05:29 UTC, Kagamin wrote:
 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.
Oct 20 2014
parent reply "Kagamin" <spam here.lot> writes:
On Monday, 20 October 2014 at 15:07:43 UTC, MrSmith wrote:
 On Monday, 20 October 2014 at 14:05:29 UTC, Kagamin wrote:
 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.
Oct 21 2014
parent reply "MrSmith" <mrsmith33 yandex.ru> writes:
On Tuesday, 21 October 2014 at 13:57:23 UTC, Kagamin wrote:
 On Monday, 20 October 2014 at 15:07:43 UTC, MrSmith wrote:
 On Monday, 20 October 2014 at 14:05:29 UTC, Kagamin wrote:
 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?
Oct 21 2014
next sibling parent "Kagamin" <spam here.lot> writes:
It's how COM casts objects 
http://msdn.microsoft.com/en-us/library/ms687230.aspx
Oct 22 2014
prev sibling parent "Kagamin" <spam here.lot> writes:
The idea is that the object you work with is responsible for 
casting itself to an interface you need.
Oct 22 2014
prev sibling parent reply Martin Nowak <code+news.digitalmars dawg.eu> writes:
On 10/20/2014 12:32 AM, MrSmith wrote:
 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.
Oct 20 2014
parent "MrSmith" <mrsmith33 yandex.ru> writes:
On Monday, 20 October 2014 at 15:30:28 UTC, Martin Nowak wrote:
 On 10/20/2014 12:32 AM, MrSmith wrote:
 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
Oct 20 2014