I want to make a dlopen on a library that uses executable’s symbols. I’m compiling gdl-0.9 on a 64bits system and I’m building a library that gdl will use dlopen. The problem is that the library uses gdl code which will be at the executable and, even though I used the -Wl,–export-dynamic flag, the program crashes and prints:
gdl: symbol lookup error: ./two.so: undefined symbol: _ZN4EnvT6NParamEj
Here is how I’ve done things:
Compiled two.cpp as the shared lib two.so.
// two.cpp
#include "envt.hpp"
using namespace std;
template< typename T>
BaseGDL* two_fun_template( BaseGDL* p0)
{
T* p0C = static_cast<T*>( p0);
T* res = new T( p0C->Dim(), BaseGDL::NOZERO);
SizeT nEl = p0->N_Elements();
for( SizeT i=0; i<nEl; ++i)
{
(*res)[ i] = 2 * ((*p0C)[ i]);
}
return res;
}
extern "C" BaseGDL* two_fun( EnvT* e)
{
SizeT nParam=e->NParam();
if (nParam != 1) {
cout << "TWO: Improper Number of Variables" << endl;
return new DLongGDL( -1);
}
BaseGDL* p0 = e->GetPar( 0);//, "TWO");
if( p0->Type() == DOUBLE)
return two_fun_template< DDoubleGDL>( p0);
else if( p0->Type() == FLOAT)
return two_fun_template< DFloatGDL>( p0);
else
{
return new DLongGDL( -1);
}
}
Used “Ubuntu 10.04.1 LTS” pre-build of gdl.
$ gdl
GDL - GNU Data Language, Version 0.9
For basic information type HELP,/INFO
'GDL_STARTUP'/'IDL_STARTUP' environment variables both not set.
No startup file read.
GDL> linkimage,'TWO','./two.so',1,'two_fun'
GDL> print, "TWO Loaded"
GDL> print, two(1.0)
gdl: symbol lookup error: ./two.so: undefined symbol: _ZN4EnvT6NParamEj
So I figured the problem was upon executing this line: SizeT nParam=e->NParam();
Next I got the gld-0.9 source code, did the whole compilation with -Wl,–export-dynamic and the same error occurred.
Next I did the whole compilation with -m32 flag (force 32bits) and:
$ ../gdl32
GDL - GNU Data Language, Version 0.9
For basic information type HELP,/INFO
'GDL_STARTUP'/'IDL_STARTUP' environment variables both not set.
No startup file read.
GDL> linkimage,'TWO','./two.so',1,'two_fun'
GDL> print, "TWO Loaded"
GDL> print, two(1.0)
2.00000
GDL>
So I guess this means its a 64bit problem, but why? I’ve searched a lot in the web and didn’t find anything other then the -Wl,–export-dynamic, maybe I didn’t know how to look or something. Can anyone help?
Btw, this is what I get when running the “nm” util.
64bits:
$ nm two.so | grep NParam
U _ZN4EnvT6NParamEj
$ nm ../gdl64 | grep NParam
00000000006dc320 T _ZN4EnvT6NParamEy
32bits:
$ nm two.so | grep NParam
U _ZN4EnvT6NParamEj
$ nm ../gdl32 | grep NParam
0830a6a0 T _ZN4EnvT6NParamEj
_ZN4EnvT6NParamEjisEnvT::NParam(unsigned int)_ZN4EnvT6NParamEyisEnvT::NParam(unsigned long long)So you should start with looking at how you include declaration of
EnvT. You need to look at what type of an argument of NParam and find where it’s redefined.