之前因為工作需要,深入研究了 rabbitmq 的 c 代碼,并以 libevent 為基礎将其改造成事件驅動的單線程模型。由于一直都是自己寫庫封裝和 demo 代碼來測試,是以上述庫都以 vs2010 的靜态庫(.lib)形式提供。前天,終于有業務人員要基于這個 demo 寫東西了,但卻發現編譯連結都不行,究其原因是由于所用的編譯器 vc6 太老舊的緣故。
庫的跨編譯器使用問題屬于老生常談,網上的資料也很多,這裡出現的内容網上也都有,可以對比參閱。
起因:
我提供了 rabbitmq 和 libevent 的靜态庫,以及相關頭檔案;業務人員在 vc6 中完整業務邏輯編寫。
現象:
編譯後,報如下錯誤
<a href="http://my.oschina.net/moooofly/blog/168927#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<code>linking...</code>
<code> </code><code>creating library ..\..\..\..\10-common\version\debug\win32\mos\mos.lib and object ..\..\..\..\10-common\version\debug\win32\mos\mos.exp</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>libevent-1.4.13.lib(signal.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_table.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>libevent-1.4.13.lib(event.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>libevent-1.4.13.lib(win32.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>libevent-1.4.13.lib(log.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_timer.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_mem.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_framing.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_mq.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_connection.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_tcp_socket.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>librabbitmq.lib(amqp_api.obj) : error lnk2001: unresolved external symbol __rtc_checkesp</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>libevent-1.4.13.lib(signal.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_table.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>libevent-1.4.13.lib(event.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>libevent-1.4.13.lib(win32.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>libevent-1.4.13.lib(log.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_timer.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_mem.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_framing.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_mq.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_connection.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_tcp_socket.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>librabbitmq.lib(amqp_api.obj) : error lnk2001: unresolved external symbol __rtc_shutdown</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>libevent-1.4.13.lib(signal.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_table.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>libevent-1.4.13.lib(event.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>libevent-1.4.13.lib(win32.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>libevent-1.4.13.lib(log.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_timer.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_mem.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_framing.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_mq.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_connection.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_tcp_socket.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>librabbitmq.lib(amqp_api.obj) : error lnk2001: unresolved external symbol __rtc_initbase</code>
<code>libevent-1.4.13.lib(log.obj) : error lnk2001: unresolved external symbol __imp____iob_func</code>
<code>librabbitmq.lib(amqp_connection.obj) : error lnk2001: unresolved external symbol __imp____iob_func</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __imp____iob_func</code>
<code>librabbitmq.lib(amqp_api.obj) : error lnk2001: unresolved external symbol __imp____iob_func</code>
<code>librabbitmq.lib(amqp_mq.obj) : error lnk2001: unresolved external symbol __imp____iob_func</code>
<code>libevent-1.4.13.lib(event.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>libevent-1.4.13.lib(win32.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>libevent-1.4.13.lib(log.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_timer.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_mem.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_framing.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_table.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_connection.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_tcp_socket.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_api.obj) : error lnk2001: unresolved external symbol @_rtc_checkstackvars@8</code>
<code>librabbitmq.lib(amqp_table.obj) : error lnk2001: unresolved external symbol ___security_cookie</code>
<code>libevent-1.4.13.lib(log.obj) : error lnk2001: unresolved external symbol ___security_cookie</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol ___security_cookie</code>
<code>librabbitmq.lib(amqp_connection.obj) : error lnk2001: unresolved external symbol ___security_cookie</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol ___security_cookie</code>
<code>librabbitmq.lib(amqp_api.obj) : error lnk2001: unresolved external symbol ___security_cookie</code>
<code>librabbitmq.lib(amqp_framing.obj) : error lnk2001: unresolved external symbol ___security_cookie</code>
<code>librabbitmq.lib(amqp_table.obj) : error lnk2001: unresolved external symbol @__security_check_cookie@4</code>
<code>libevent-1.4.13.lib(log.obj) : error lnk2001: unresolved external symbol @__security_check_cookie@4</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol @__security_check_cookie@4</code>
<code>librabbitmq.lib(amqp_connection.obj) : error lnk2001: unresolved external symbol @__security_check_cookie@4</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol @__security_check_cookie@4</code>
<code>librabbitmq.lib(amqp_api.obj) : error lnk2001: unresolved external symbol @__security_check_cookie@4</code>
<code>librabbitmq.lib(amqp_framing.obj) : error lnk2001: unresolved external symbol @__security_check_cookie@4</code>
<code>libevent-1.4.13.lib(signal.obj) : error lnk2001: unresolved external symbol __imp___wassert</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __imp___wassert</code>
<code>librabbitmq.lib(amqp_mem.obj) : error lnk2001: unresolved external symbol __imp___wassert</code>
<code>libevent-1.4.13.lib(event.obj) : error lnk2001: unresolved external symbol __imp___wassert</code>
<code>libevent-1.4.13.lib(win32.obj) : error lnk2001: unresolved external symbol __imp___wassert</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __imp__freeaddrinfo@4</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __imp__getaddrinfo@16</code>
<code>librabbitmq.lib(amqp_socket.obj) : error lnk2001: unresolved external symbol __rtc_uninituse</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol __imp___strtoi64</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol __imp___ftime64</code>
<code>libevent-1.4.13.lib(evutil.obj) : error lnk2001: unresolved external symbol __imp___vscprintf</code>
<code>..\..\..\..\10-common\version\debug\win32\mos\mos.exe : fatal error lnk1120: 14 unresolved externals</code>
<code>error executing link.exe.</code>
<code>mos.exe - 85 error(s), 0 warning(s)</code>
上述錯誤大緻可以分為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 版本,而這種方式提供的庫,上述三種錯誤都不會發生,即不需要按上面的方式設定各種值。