-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

AltStyle によって変換されたページ (->オリジナル) /