[英]Makefile, how to link 32bits library and 64bits library at the same time
[英]Symbol Lookup Error: Combining Executable and Library on 64bits
我想在使用可執行文件符號的庫上創建dlopen。 我正在64位系統上編譯gdl-0.9,並且正在構建一個庫,該庫將使用dlopen。 問題在於該庫使用的gdl代碼將位於可執行文件中,即使我使用了-Wl,-export -dynamic標志,該程序也會崩潰並打印:gdl:符號查找錯誤:./two.so:未定義的符號:_ZN4EnvT6NParamEj
這是我的工作方式:
將two.cpp編譯為共享庫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);
}
}
使用gdl的“ Ubuntu 10.04.1 LTS”預構建版本。
$ 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
因此,我認為問題出在執行以下代碼行:SizeT nParam = e-> NParam();
接下來,我得到了gld-0.9源代碼,使用-Wl,-export-dynamic進行了整個編譯,並發生了相同的錯誤。
接下來,我使用-m32標志(強制32位)完成了整個編譯,並且:
$ ../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>
所以我想這意味着它是一個64位的問題,但是為什么呢? 我在網上搜索了很多東西,除了-Wl,-export-dynamic之外 ,再也找不到其他東西,也許我不知道該如何看。 有人可以幫忙嗎?
順便說一句,這是我在運行“ nm”實用程序時得到的。
64位:
$ nm two.so | grep NParam
U _ZN4EnvT6NParamEj
$ nm ../gdl64 | grep NParam
00000000006dc320 T _ZN4EnvT6NParamEy
32位:
$ nm two.so | grep NParam
U _ZN4EnvT6NParamEj
$ nm ../gdl32 | grep NParam
0830a6a0 T _ZN4EnvT6NParamEj
_ZN4EnvT6NParamEj
是EnvT::NParam(unsigned int)
_ZN4EnvT6NParamEy
是EnvT::NParam(unsigned long long)
因此,您應該首先查看如何包括EnvT
聲明。 您需要查看NParam參數的類型,並找到在何處重新定義。
我不知道您是否仍然可以使用該幫助,但是要為64位編譯這兩個函數和所有其他函數,應在g ++命令中添加-DHAVE_64BIT_OS選項。 這樣,預處理器可以在typedefs.hpp中為SizeT設置正確的類型。 所以編譯將
g ++ -DHAVE_64BIT_OS -I /(gdl src的路徑)-c two.cpp -fpic
所有其他命令保持不變。
從nm
輸出看起來好像類型不同-可執行文件具有_ZN4EnvT6NParamEy
而庫需要_ZN4EnvT6NParamEj
。 如您所見,最后一個字母有所不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.