www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problems with Reflection in Static library

reply Mandeep Singh Brar <mandeep brars.co.in> writes:
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
Dec 17 2010
next sibling parent reply Tomek =?ISO-8859-2?Q?Sowi=F1ski?= <just ask.me> writes:
Mandeep Singh Brar napisa=B3:

 I have a class A in module testD as follows
=20
 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);
 	}
 }
=20
 I have another file which uses this class as follows:
=20
 module user;
 import std.stdio;
=20
 int main() {
 	Object obj =3D Object.factory("testD.A");
 	if(obj is null)
 		writeln("null object");
 	else
 		writeln("object created");
 	return 0;
 }
=20
 When i compile the class A as "dmd -c -of testD testD.d" and the second f=
ile as "dmd user.d testD",
 the example works fine and the object gets created.
=20
 But When i compile the class A as "dmd -c -lib testD.d" and the second fi=
le as "dmd user.d testD.a",
 the example gives me a null object.
=20
 The Object.factory method does not seem to work if my class has been comp=
iled as a static library.
 Can you please let me know how to solve this. I have tried replacing publ=
ic with export for class
 testD, but that does not help.
I think dmd creates type information for each compilation, but doesn't mer= ge it when linking. I hope it's a bug and will also be fixed for dynamic li= bs. 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 re= turn a factory. Sure, one can get used to it, but why not Object.make or .c= reate or .instance? --=20 Tomek
Dec 18 2010
next sibling parent spir <denis.spir gmail.com> writes:
On Sat, 18 Dec 2010 13:07:41 +0100
Tomek Sowi=C5=84ski <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) do= es return a slice!) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Dec 18 2010
prev sibling parent reply Mandeep Singh Brar <mandeep brars.co.in> writes:
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
Dec 18 2010
parent Stanislav Blinov <blinov loniir.ru> writes:
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).
Dec 20 2010
prev sibling parent Kagamin <spam here.lot> writes:
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.
Dec 18 2010