-shared option
Ranjit Mathew
rmathew4lists@hotmail.com
Thu Apr 3 10:35:00 GMT 2003
> You need to mark DATA
>
> > ---------------------------- 8< --------------------------------
> > EXPORTS
> > _ZN3Foo3barEv
> > _ZN3FooC1Ev
> _ZN3Foo6class$E DATA
> _ZTVN3FooE DATA
> > ---------------------------- 8< --------------------------------
>
> The other way:
> dlltool --output-def foo.def --export-all foo.o
> and then comment out what you don't want to export.
Did this, tried "-Wl,--export-all-symbols", "-Wl,--enable-auto-import",
etc. but am still getting the NullPointerException. :-(
On closer inspection, among the lines:
System.out.println( "Test 1...");
Foo f;
System.out.println( "Test 2...");
f = new Foo( );
System.out.println( "Test 3...");
f.bar( );
System.out.println( "Test 4...");
the NullPointerException happens just at the line creating the
new Foo object, so a WAG would be that the class definition is
not being loaded properly.
(Which suddenly makes me realise that I haven't got the foggiest
idea about how GCJ is able to determine class layout, method and
variable information etc. when it doesn't have the convenience
of a header file as in C++... Anyone care to enlighten?
[And *this* tells me that I seem to have a penchant for forking
off off-topic threads in a discussion. ;-)])
> You can only access DATA like this
>
> *_imp__ZTVN3FooE
>
> so you either
> (1) need the dllimport for imported objects in client code
> (2) use --enable auto-import and (probabaly) --enable-runtime-pseudo-reloc to
> fixup
This merits a bit more explanation for the non-Windows folks
in here I guess (time to show off some recently acquired,
probably flaky, knowledge ;-)):
As the harried non-Windows members of this list might know
by now, a DLL on Windows needs to explicitly export symbols
corresponding to a variable or a method for the linker/loader
to be able to resolve it. This is done by either marking
them "__declspec(dllexport)" or explicitly listing them in
a separate exports definition file ("DEF file").
For a call to a method that is declared *without* any
import attributes, the generated call would look roughly
like:
call _foo
Now if the object file containing "foo( )" is linked in
directly or if it is in a statically linked library, every
thing is hunky dory.
However, if "foo( )" is defined in a dynamic library, the
linker puts in the following magic (roughly) for this case:
_foo:
movl __imp__foo, %eax
jmp *%eax
"__imp__foo" comes from the import table of the executable
and is "fixed up" by the Windows loader based on the loaded
"foo" DLL.
If "foo( )" were to be declared "__declspec(dllimport)",
this double-indirection can be avoided and the program
would be that much faster (noticeably so on older Pentiums).
So how does one declare "foo( )" in such a way that
it gets defined in the best manner possible for
statically linked-in clients as well as dynamically linked in
clients? Something like the following is used:
#ifdef LIBFOO_DLL
#ifdef FOO_IMPLEMENTATION
int __declspec(dllexport) foo( void);
#else
int __declspec(dllimport) foo( void);
#endif
#else
int foo( void);
#endif
Gross, eh? A similar mechanism can be seen today in the "jni.h"
header in GCJ (see "JNIIMPEXP").
For data, a similar magic takes place - the
"--enable-auto-import" flag makes the linker link "_bar" to
"__imp__bar".
The point of all this explanation being that if GCJ has
to generate nice code that works with classes defined in a
DLL as well as in a static library *without* the user
being able to indicate it using an attribute, we need
some more magic...
> Note there are fish-hooks in C++ with dllimport and virtual methods and
> artificial variables (eg, typeinfo objects) generated by the compiler. I expect
> the same in Java.
This was OHT (Over-Head Transmission) for me... :-(
Ranjit.
More information about the Java
mailing list