Thread overview
Problems with Reflection in Static library
Dec 18, 2010
Mandeep Singh Brar
Dec 18, 2010
Tomek Sowiński
Dec 18, 2010
spir
Dec 19, 2010
Mandeep Singh Brar
Dec 20, 2010
Stanislav Blinov
Dec 18, 2010
Kagamin
December 18, 2010
Hi,

Please excuse for a longish mail, but i am putting the complete question.

I have a class A in module testD as follows

module testD;
import std.stdio;
public class A {
	public this() {
		writeln("const");
	}
	public void a(string l, int k) {
		writeln("Hello B.a", l, k);
	}
}

I have another file which uses this class as follows:

module user;
import std.stdio;

int main() {
	Object obj = Object.factory("testD.A");
	if(obj is null)
		writeln("null object");
	else
		writeln("object created");
	return 0;
}

When i compile the class A as "dmd -c -of testD testD.d" and the second file as "dmd user.d testD", the example works fine and the object gets created.

But When i compile the class A as "dmd -c -lib testD.d" and the second file as "dmd user.d testD.a", the example gives me a null object.

The Object.factory method does not seem to work if my class has been compiled as a static library. Can you please let me know how to solve this. I have tried replacing public with export for class testD, but that does not help.

Thanks for reading the mail.
Mandeep
December 18, 2010
Mandeep Singh Brar napisał:

> I have a class A in module testD as follows
> 
> module testD;
> import std.stdio;
> public class A {
> 	public this() {
> 		writeln("const");
> 	}
> 	public void a(string l, int k) {
> 		writeln("Hello B.a", l, k);
> 	}
> }
> 
> I have another file which uses this class as follows:
> 
> module user;
> import std.stdio;
> 
> int main() {
> 	Object obj = Object.factory("testD.A");
> 	if(obj is null)
> 		writeln("null object");
> 	else
> 		writeln("object created");
> 	return 0;
> }
> 
> When i compile the class A as "dmd -c -of testD testD.d" and the second file as "dmd user.d testD", the example works fine and the object gets created.
> 
> But When i compile the class A as "dmd -c -lib testD.d" and the second file as "dmd user.d testD.a", the example gives me a null object.
> 
> The Object.factory method does not seem to work if my class has been compiled as a static library. Can you please let me know how to solve this. I have tried replacing public with export for class testD, but that does not help.

 I think dmd creates type information for each compilation, but doesn't merge it when linking. I hope it's a bug and will also be fixed for dynamic libs.

A (not nice) workaround may be exposing in your lib:

Object objectFactory(string name) {
	return Object.factory(name);
}

and calling it in your program. This should look for the type name in your lib's info.

BTW, am I the only one to think Object.factory is a bad name? It doesn't return a factory. Sure, one can get used to it, but why not Object.make or .create or .instance?

-- 
Tomek

December 18, 2010
On Sat, 18 Dec 2010 13:07:41 +0100
Tomek Sowiński <just@ask.me> wrote:

> BTW, am I the only one to think Object.factory is a bad name? It doesn't return a factory. Sure, one can get used to it, but why not Object.make or .create or .instance?

You're not the only one ;-)
Similar to index(ing) not returning an index, but the element at said index --reason why I like and use "element" or "elementAt". (While slice(ing) does return a slice!)

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

December 18, 2010
Mandeep Singh Brar Wrote:

> The Object.factory method does not seem to work if my class has been compiled as a static library. Can you please let me know how to solve this. I have tried replacing public with export for class testD, but that does not help.

The class A is not referenced from module user, so the linker thinks, it's not used and doesn't compile it in (you don't pay for what you don't use). This applies to libraries. Objects are included entirely.
Libraries can be of any size, but included is only needed stuff. Consider phobos library is 3MB size, you don't want it to be fully included in your every application, do you? But if you want to use its arbitrary members at runtime, you'll need to have them all.
December 19, 2010
Thanks a lot for your reply Tomek. I understand what you are saying but this would not work for me. The reason is that i am trying to make some kind of plugins from these libs. So i would not know the name objectFactory also in advance (multiple plugins will not be implementing the same named method and linking statically).

For now i am just merging these two into the same place.

Regards
Mandeep
December 20, 2010
19.12.2010 10:51, Mandeep Singh Brar пишет:
> Thanks a lot for your reply Tomek. I understand what you are saying
> but this would not work for me. The reason is that i am trying to
> make some kind of plugins from these libs. So i would not know the
> name objectFactory also in advance (multiple plugins will not be
> implementing the same named method and linking statically).
>
> For now i am just merging these two into the same place.
In general, it's not a very good idea to make plugins using static linkage. Even if your plugins will be dynamic libraries (dll/so), which is currently not possible at least on Linux (and at least with dmd, I don't know about gdc2), but the core to which they are plugged-in remains static library, you may and most certainly will get unpleasant surprises. Reason being, any static data contained in the static library will be duplicated for every executable/dll that links to it. I don't know if anything can be done with it (actually, I think nothing can be). So for plugins, it's better to keep the 'core' also as a dynamic library. But, again, dmd is currently is not on good terms with dynamic linking (aside from loading a C dll at runtime, but that doesn't count).