Plugins and D programs
Steve Teale
steve.teale at britseyeview.com
Fri Mar 14 00:46:24 PDT 2014
On Friday, 14 March 2014 at 06:54:34 UTC, Steve Teale wrote:
> On Thursday, 13 March 2014 at 21:20:10 UTC, Tolga Cakiroglu
> It is not just a shut-down artefact, since if I repeat the
> exercise with an exemplar class instead of an interface, then
> it will work.
OK, so here's an example using an exemplar base class instead of
an interface. This includes making the exemplar class implement
an interface.
Here's the exemplar class, and another class that references an
instance of it:
module bc;
import std.stdio;
interface I
{
string saySomething();
}
class Bc: I
{
string saySomething() { return null; };
}
class Other
{
I target;
this(I i) { target = i; }
void invokeWithCast() { writeln((cast(Bc)
target).saySomething()); }
void invoke() { writeln(target.saySomething()); }
}
Then the plugin:
module plugin;
import bc;
import std.stdio;
class Plugin: Bc
{
this() { writeln("plugin ctor"); }
override string saySomething() { return "I am plugin"; }
}
Bc getInstance()
{
return new Plugin();
}
And the program:
module main;
import core.runtime;
import std.stdio;
import bc;
extern(C) void* dlsym(void*, const char*);
alias Bc function() pfi;
Bc getPlugin(string name)
{
void* lib = Runtime.loadLibrary(name~".so");
void* vp = dlsym(lib, "_D6plugin11getInstanceFZC2bc2Bc\0".ptr);
pfi f = cast(pfi) vp;
Bc x = f();
return x;
}
void main()
{
Bc x = getPlugin("plugin");
writeln(x.saySomething()); // OK
Other other = new Other(x);
other.invokeWithCast(); // OK
other.invoke(); // Crash
}
Built with:
main : bc.d main.d
dmd -c bc.d
dmd -c main.d
dmd main.o bc.o -L-L/usr/local/lib -L-ldl -L-lgtkd-2
-defaultlib=libphobos2.so -L-rpath=.
plugin : plugin.d
dmd -c -shared -fPIC plugin.d
dmd plugin.o -shared -defaultlib=libphobos2.so -map
clean :
rm *.o
rm main
rm plugin.so
Output:
steve at steve-desktop:~/scratch/pibc$ ./main
plugin ctor
I am plugin
I am plugin
Segmentation fault (core dumped)
If you comment out the last call via the interface instance with
no cast, the program exits cleanly. So the problem does seem to
relate to interfaces.
So you can do it, but if the base class conforms to some
interface, then you have to special-case calls to the interface
functions. That rather destroys the utility of classes like Other
which provide services to the installed plugin.
My gut-feeling question is "is the vtable in the program or the
plugin, and does this vary when the plugin implements an
interface?"
I'm hoping Martin Nowak might join in this discussion.
Steve
More information about the Digitalmars-d
mailing list