以前由於工做須要,深刻研究了 rabbitmq 的 C 代碼,並以 libevent 爲基礎將其改形成事件驅動的單線程模型。因爲一直都是本身寫庫封裝和 demo 代碼來測試,因此上述庫都以 VS2010 的靜態庫(.lib)形式提供。前天,終於有業務人員要基於這個 demo 寫東西了,但卻發現編譯連接都不行,究其緣由是因爲所用的編譯器 VC6 太老舊的緣故。
庫的跨編譯器使用問題屬於老生常談,網上的資料也不少,這裏出現的內容網上也都有,能夠對比參閱。
原由:
我提供了 rabbitmq 和 libevent 的靜態庫,以及相關頭文件;業務人員在 VC6 中完整業務邏輯編寫。
現象:
編譯後,報以下錯誤
Linking...
Creating library ..\..\..\..\10-common\version\debug\win32\mos\mos.lib and object ..\..\..\..\10-common\version\debug\win32\mos\mos.exp
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
libevent-1.4.13.lib(signal.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_table.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
libevent-1.4.13.lib(event.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
libevent-1.4.13.lib(win32.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
libevent-1.4.13.lib(log.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_timer.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_mem.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_framing.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_mq.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_connection.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_tcp_socket.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
librabbitmq.lib(amqp_api.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
libevent-1.4.13.lib(signal.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_table.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
libevent-1.4.13.lib(event.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
libevent-1.4.13.lib(win32.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
libevent-1.4.13.lib(log.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_timer.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_mem.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_framing.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_mq.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_connection.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_tcp_socket.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
librabbitmq.lib(amqp_api.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
libevent-1.4.13.lib(signal.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_table.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
libevent-1.4.13.lib(event.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
libevent-1.4.13.lib(win32.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
libevent-1.4.13.lib(log.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_timer.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_mem.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_framing.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_mq.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_connection.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_tcp_socket.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
librabbitmq.lib(amqp_api.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
libevent-1.4.13.lib(log.obj) : error LNK2001: unresolved external symbol __imp____iob_func
librabbitmq.lib(amqp_connection.obj) : error LNK2001: unresolved external symbol __imp____iob_func
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __imp____iob_func
librabbitmq.lib(amqp_api.obj) : error LNK2001: unresolved external symbol __imp____iob_func
librabbitmq.lib(amqp_mq.obj) : error LNK2001: unresolved external symbol __imp____iob_func
libevent-1.4.13.lib(event.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
libevent-1.4.13.lib(win32.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
libevent-1.4.13.lib(log.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_timer.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_mem.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_framing.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_table.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_connection.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_tcp_socket.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_api.obj) : error LNK2001: unresolved external symbol @_RTC_CheckStackVars@8
librabbitmq.lib(amqp_table.obj) : error LNK2001: unresolved external symbol ___security_cookie
libevent-1.4.13.lib(log.obj) : error LNK2001: unresolved external symbol ___security_cookie
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol ___security_cookie
librabbitmq.lib(amqp_connection.obj) : error LNK2001: unresolved external symbol ___security_cookie
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol ___security_cookie
librabbitmq.lib(amqp_api.obj) : error LNK2001: unresolved external symbol ___security_cookie
librabbitmq.lib(amqp_framing.obj) : error LNK2001: unresolved external symbol ___security_cookie
librabbitmq.lib(amqp_table.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
libevent-1.4.13.lib(log.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
librabbitmq.lib(amqp_connection.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
librabbitmq.lib(amqp_api.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
librabbitmq.lib(amqp_framing.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
libevent-1.4.13.lib(signal.obj) : error LNK2001: unresolved external symbol __imp___wassert
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __imp___wassert
librabbitmq.lib(amqp_mem.obj) : error LNK2001: unresolved external symbol __imp___wassert
libevent-1.4.13.lib(event.obj) : error LNK2001: unresolved external symbol __imp___wassert
libevent-1.4.13.lib(win32.obj) : error LNK2001: unresolved external symbol __imp___wassert
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __imp__freeaddrinfo@4
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __imp__getaddrinfo@16
librabbitmq.lib(amqp_socket.obj) : error LNK2001: unresolved external symbol __RTC_UninitUse
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol __imp___strtoi64
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol __imp___ftime64
libevent-1.4.13.lib(evutil.obj) : error LNK2001: unresolved external symbol __imp___vscprintf
..\..\..\..\10-common\version\debug\win32\mos\mos.exe : fatal error LNK1120: 14 unresolved externals
Error executing link.exe.
mos.exe - 85 error(s), 0 warning(s)
上述錯誤大體能夠分爲3類:
- error LNK2001: unresolved external symbol __RTC_xxx
- error LNK2001: unresolved external symbol @__security_xxx
- error LNK2001: unresolved external symbol __imp__xxx
對於第一類錯誤 -
RTC 錯誤,
是 VS2005 及以上版本編譯器的 Runtime Check 運行時檢查
致使的。
在編譯 lib 時,若是選擇了「運行時檢查」,那麼別的應用程序在連接這個庫文件的時候,就會報這樣的錯。
爲了能讓 lib 庫文件在 VS2010 和 VC6 上通用,須要用如下的方法,再重編一下庫:
屬性
-> 配置屬性 -> C/C++ -> 代碼生成 -> 基本運行時檢查(Basic Runtime Checks) 改成「默認(Default)」
對於第二類錯誤 -
security 錯誤,是因爲緩衝區安全檢查致使的,需作以下設置:
屬性 -> 配置屬性 -> C/C++ > 代碼生成 > 緩衝區安全檢查,將值改成「否(/GS-)」
對於第三類錯誤 - 運行時庫未實現相應函數,或實現的函數名字不一樣致使的錯誤,在使用靜態庫的狀況下未找到合適的辦法解決。
因爲上面第三類錯誤未可以解決,因此只能改變庫的提供方式,改爲提供相應庫的 dll 版本,而這種方式提供的庫,上述三種錯誤都不會發生,即不須要按上面的方式設置各類值。
建議:
- 跨(windows)編譯器的狀況下最好不要使用靜態庫方式,應該使用動態庫方式提供。
- 庫的編譯中使用的運行時最好保持一致。