簡體   English   中英

未定義參考:怎么了?

[英]undefined reference to : what's wrong?

我正在嘗試將自制軟件從 AIX 移植到“Red Hat Enterprise Linux 7.8”

我在鏈接時面臨“未定義的引用”錯誤,現在,我找不到我搞砸的地方。

目標是從 2 個自制共享庫( msiatmi )、一些以前編譯的 object(MsiServices.o)和一個 C 程序(pingsrv.c)生成可執行文件。 下面是命令:

gcc -DWall -o bin/pingsrv -DUNIX -I. -g -DUNIX -D_THREAD_SAFE -D_LARGEFILE64_SOURCE -I/home/vgi/git/msi-tools/ping/server/target/msi/include/yaml-cpp -I/home/vgi/git/msi-tools/ping/server/target/msi/include/apr-1 -I/home/vgi/git/msi-tools/ping/server/target/msi/include/activemq-cpp-3.9.4 -I/home/vgi/git/msi-tools/ping/server/target/msi/include /tmp/MsiServices.o ./pingsrv.c -L/home/vgi/git/msi-tools/ping/server/target/msi/lib -lmsi -lactivemq-cpp -llog4cxx -latmi -lapr-1 -laprutil-1 -lexpat -lstdc++ -lyaml-cpp

錯誤出現鏈接時間:

/home/vgi/git/msi-tools/ping/server/target/msi/lib/libatmi.so: undefined reference to `Msi_tpreturn'
/home/vgi/git/msi-tools/ping/server/target/msi/lib/libatmi.so: undefined reference to `Msi_tpcall'
/home/vgi/git/msi-tools/ping/server/target/msi/lib/libmsi.so: undefined reference to `msi::service::optarg'
/home/vgi/git/msi-tools/ping/server/target/msi/lib/libatmi.so: undefined reference to `Msi_userlog'

庫 atmi 是用 C 編寫的,並且能夠通過使用包裝器調用一些 C++ 實例方法:

...
typedef struct MsiScheduler MsiScheduler ;
extern void Msi_tpreturn(MsiScheduler *,int, long , char *, long, long);
extern void Msi_userlog(MsiScheduler *,char*) ;
extern int Msi_tpcall(MsiScheduler *,char *svc, char *idata, long ilen, char **odata, long *olen, long flags) ;
...
extern void tpreturn(int rval, long rcode, char * data, long len, long flags)
{
    assert(vg_Consumer != NULL) ;
    Msi_tpreturn(vg_Consumer,rval,rcode,data,len,flags) ;

}

此庫調用的包裝器在另一個名為msi的庫中定義。 包裝器在 C++ 源文件 (MsiScheduler.cpp) 中定義:

void Msi_tpreturn(MsiScheduler * c,int ret,long code,char *data,long len,long flags)
{
    TypedBuffer* buffer = NULL ;

    if (data != NULL)
    {
       buffer = TypedBuffer::createBuffer(getType(data),data,len) ; 
    }
    MsiReply * reply = MsiReply::createReply(ret,code,buffer) ;

    c->tpreturn(reply) ;

    if (data != NULL)
    {
       freebuf(data) ;
    }
    delete reply ;
}
int Msi_tpcall(MsiScheduler * c,char *svc, char *idata, long ilen, char **odata, long *olen, long flags)
{
     ...
}
void Msi_userlog(MsiScheduler *c ,char* str)
{
    c->userlog(str) ;
}

header 文件 (MsiScheduler.h) 包含以下片段:

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__STDC__) || defined(__cplusplus)
extern void Msi_tpreturn(MsiScheduler *,int, long , char *, long, long);
extern void Msi_userlog(MsiScheduler *,char*) ;
extern int Msi_tpcall(MsiScheduler *,char *svc, char *idata, long ilen, char **odata, long *olen, long flags) ;
#else
extern void Msi_tpreturn();
extern void Msi_userlog() ;
extern int Msi_tpcall() ;
#endif

#ifdef __cplusplus
}
#endif

圖書館是這樣構建的:

g++ -g -fPIC -Wall -I/home/vgi/git/msi/msi-service/target/ext/include/apr-1 -I/home/vgi/git/msi/msi-service/target/ext/include/activemq-cpp-3.9.4 -I/home/vgi/git/msi/msi-service/target/ext/include/yaml-cpp -I/home/vgi/git/msi/msi-service/target/ext/include -I/home/vgi/git/msi/msi-service/target/ext/include -I../lib/inc -I./ -o MsiScheduler.o -c MsiScheduler.cpp
...
g++ -shared MsiUtil.o MsiConfig.o MsiInstrumentation.o MsiMetric.o MsiService.o MsiExceptions.o MsiCharsetConverter.o MsiTypes.o MsiMessage.o MsiMessageUtil.o MsiScheduler.o MsiServer.o -o libmsi.so
...
gcc -g -fPIC -Wall -I/home/vgi/git/msi/msi-service/target/ext/include/apr-1 -I/home/vgi/git/msi/msi-service/target/ext/include/activemq-cpp-3.9.4 -I/home/vgi/git/msi/msi-service/target/ext/include/yaml-cpp -I/home/vgi/git/msi/msi-service/target/ext/include -I/home/vgi/git/msi/msi-service/target/ext/include -I../lib/inc -I./ -o atmi.o -c atmi.c
gcc -shared atmi.o memmngt.o -o libatmi.so

僅供參考,一切都可以在 AIX OS 上很好地編譯和鏈接(使用 xlc、xlC 命令)。

我還嘗試更改鏈接命令的庫順序,但沒有成功。

我想有一些特定於 linux/gcc 的東西,但我還沒有找到它。

 libmsi.so:0000000000034f20 T _Z10Msi_tpcallPN3msi7service12MsiSchedulerEPcS3_lPS3_Pll libmsi.so:0000000000035138 T _Z11Msi_userlogPN3msi7service12MsiSchedulerEPc libmsi.so:0000000000034e55 T _Z12Msi_tpreturnPN3msi7service12MsiSchedulerEilPcll libatmi.so: U Msi_tpcall libatmi.so: U Msi_tpreturn libatmi.so: U Msi_userlog

在你的nm output 中, T的意思是右邊的符號是在 libmsi.so 中定義的,而U的意思是右邊的符號是 libatmi.so 需要的。 但顯然,這些符號的名稱不匹配。 libmsi.so 中的名稱具有 C++ 修飾符,這有助於將重載函數分開。

這意味着在編譯 MsiScheduler.cpp 時, extern "C"不適用於 function 定義。 確保它包含 MsiScheduler.h,並且任何#if都不會跳過 header 的那部分。 如果這不是問題,請仔細檢查 MsiScheduler.h 聲明和 MsiScheduler.cpp 定義中的 function 參數類型是否完全相同,盡管它們似乎是。

當您編譯 pingsrv.c 時,您嘗試將 msi 與 -l 鏈接。 您是否將 libmsi.so 放在庫路徑中以便 -l 可以找到它?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM