2010-11-25 4 views
2

Ich möchte eine DLL in einer Bibliothek erstellen, die Symbole der ausführbaren Datei verwendet. Ich kompiliere gdl-0.9 auf einem 64-Bit-System und ich baue eine Bibliothek, die gdl dlopen verwenden wird. Das Problem ist, dass die Bibliothek gdl Code verwendet, die an der ausführbaren Datei sein werden und, obwohl ich den -Wl verwendet, - Export-dynamische Flag, das Programm stürzt ab und druckt: gdl: Symbol Lookup-Fehler:. /two.so: undefined Symbol: _ZN4EnvT6NParamEjSymbol Lookup Error: Kombinieren von ausführbaren Datei und Bibliothek auf 64 Bit

Hier ist, wie ich habe Dinge getan:

Zusammengestellt two.cpp als gemeinsam genutzter 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); 
    } 
} 

Verwendet "Ubuntu 10.04.1 LTS" Pre-Build von 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 

Also habe ich das Problem bei der Ausführung dieser Linie war: SizeT nParam = e-> nParam();

Als nächstes habe ich den GLD-0.9-Quellcode, habe die ganze Sammlung mit -Wl, - Export-dynamischen und dem gleichen Fehler aufgetreten.

Als nächstes habe ich die ganze Sammlung mit -m32 Flagge (Kraft 32bits) und:

$ ../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> 

Also ich denke, das bedeutet, es ist ein 64-Bit-Problem, aber warum? Ich habe viel im Web gesucht und fand nichts anderes als die -Wl, - Export-dynamische, vielleicht wusste ich nicht, wie man oder etwas aussieht. Kann jemand helfen?

Btw, das ist, was ich bekomme, wenn das "nm" util läuft.

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 
+1

Es sieht so aus, als ob Ihre Header nicht mit der kompilierten Bibliothek über die Größe von 'SizeT' typedef übereinstimmen. Insbesondere scheint die Bibliothek einen 64-Bit-Rückgabewert zu verwenden, und "two.so" erwartet 32 ​​Bit. Versuchen Sie, die Symbole von "nm" bis "C++ filt" auszuführen, um zu sehen, welchen genauen Typen "j" und "y" entsprechen. –

Antwort

3

_ZN4EnvT6NParamEjEnvT::NParam(unsigned int)
_ZN4EnvT6NParamEy ist EnvT::NParam(unsigned long long)

So sollten Sie mit Blick auf beginnen, wie Sie Erklärung EnvT umfassen. Sie müssen sich anschauen, welche Art von Argument von NParam verwendet wird und wo es neu definiert wird.

+0

Vielen Dank für Ihre Hilfe. – Rodro

0

Von der nm Ausgabe sieht es aus wie die Typen sind unterschiedlich - die ausführbare Datei hat _ZN4EnvT6NParamEy, während die Bibliothek _ZN4EnvT6NParamEj will. Wie Sie sehen können, unterscheidet sich der letzte Buchstabe.

+0

Vielen Dank, ich habe den Unterschied gesehen, aber ich wusste nicht, was es war – Rodro

1

Ich weiß nicht, ob Sie immer noch die Hilfe verwenden können, aber zum Kompilieren der beiden Funktionen und aller anderen für 64 Bit sollten Sie die Option -DHAVE_64BIT_OS zum Befehl g ++ hinzufügen. Auf diese Weise stellt der Präprozessor in typedefs.hpp den richtigen Typ für SizeT ein. Kompilieren So

g ++ -DHAVE_64BIT_OS -I/(Pfad zum gdl src) wird -c two.cpp -fpic

Alle anderen Befehle bleiben gleich.

+0

Ich fand heraus, dass nach den Menschen die Unterschiede hingewiesen. Danke dir trotzdem. – Rodro