討論區快速選單
知識庫快速選單
網路投保旅行平安險 政府補助!學嵌入式+物聯網 討論區最近新進100則主題
[ 回上頁 ] [ 討論區發言規則 ]
為何一個 static 的成員變數被當成 "無法解析的外部符號"?
更改我的閱讀文章字型大小
作者 : hgffly() 貼文超過200則人氣指數超過10000點
[ 貼文 246 | 人氣 23261 | 評價 290 | 評價/貼文 1.18 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/6/3 下午 09:08:17
各位大大好,小弟我寫了一個簡單的測試code,在編譯時遇到一個令我非常不解的 error

// testDlg.h : 標頭檔
class __declspec(dllexport) CA //因為我要建立 dll 檔,所以加了 __declspec(dllexport) 這個修飾詞
{
static int num[10];
int fun() { return num[0]; }
};
// CtestDlg 對話方塊
class CtestDlg : public CDialog
{
    ............................
};

會出現如下的錯誤訊息
1>test.obj : error LNK2001: 無法解析的外部符號 "private: static int * CA::num" (?num@CA@@0PAHA)
1>testDlg.obj : error LNK2001: 無法解析的外部符號 "private: static int * CA::num" (?num@CA@@0PAHA)
1>C:\test.exe : fatal error LNK1120: 1 個無法解析的外部符號

然後我把變數 num 的 static 修飾詞拿掉,code 如下,編譯就成功了
class __declspec(dllexport) CA
{
int num[10]; //把 static 拿掉
int fun() { return num[0]; }
};
因為我宣告的多個 CA 物件,只需要用到一個 num 實體,所以我才將它宣告成 static,只是令我很不解的是這變數明明就有宣告,為什還會被當成 無法解析的外部符號 呢?
希望大大能幫小弟解決困惑!謝謝!!!
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人hgffly註記此篇回應為最佳解答 2012/6/3 下午 10:45:13
int num[10];成員有定義,沒實體,當然無法解析。
你要在程式檔加上 int CA::num[10];這個實體宣告。
作者 : hgffly(飛) 貼文超過200則人氣指數超過10000點
[ 貼文 246 | 人氣 23261 | 評價 290 | 評價/貼文 1.18 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/6/4 下午 04:39:08
可以了!謝謝!
作者 : hgffly(飛) 貼文超過200則人氣指數超過10000點
[ 貼文 246 | 人氣 23261 | 評價 290 | 評價/貼文 1.18 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/10/24 上午 08:20:05
不好意思,想針對這原本的問題再提出後來遇到的另一個問題,就是我的 CA 之前原本和 Dialog 是在同一個專案下,
後來我將 CA 和 Dialog 這兩個分在兩個不同的專案,CA是 dll 專案,在 vc2010 編譯時,還是會出現同樣的問題
即如果 Dialog 這檔案有用到 CA 的 num 就會出現錯誤,假如只有 CA 本身的專案用到這變數則不會有錯誤,
我後來有去網路發現也有人遇到和我一樣的問題,原文請參考下列網址:
http://stackoverflow.com/questions/2479784/exporting-static-data-in-a-dll

而有人回應如下:

The static member is not accessed directly by code in the calling application, only through member functions of the class in the dll. However there are several inline functions accessing the static member. Those functions will be inline expanded into the calling applications code makeing the calling application access the static member directly. That will violate the finding referenced above that static variables are local to the dll and cannot be referenced from the calling application.

而我也有找到另一個回文:
You can not export data fields from a DLL. You can only export functions!
The reason is simple. The binding mechanism for function to a DLL have a jump table where the final reference from the DLL is set into.Because the load address is unknown it is not possible to unreference a variable in a DLL.
Write a function that returns that static value!

從這兩個回文來看應該是說 dll 裡的 static 變數不能直接去 access 它,但還是不太瞭解它的原理,不知是否有哪位大大能幫小弟解惑一下,謝謝!
作者 : hgffly(飛) 貼文超過200則人氣指數超過10000點
[ 貼文 246 | 人氣 23261 | 評價 290 | 評價/貼文 1.18 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/10/24 上午 08:20:17
不好意思,想針對這原本的問題再提出後來遇到的另一個問題,就是我的 CA 之前原本和 Dialog 是在同一個專案下,
後來我將 CA 和 Dialog 這兩個分在兩個不同的專案,CA是 dll 專案,在 vc2010 編譯時,還是會出現同樣的問題
即如果 Dialog 這檔案有用到 CA 的 num 就會出現錯誤,假如只有 CA 本身的專案用到這變數則不會有錯誤,
我後來有去網路發現也有人遇到和我一樣的問題,原文請參考下列網址:
http://stackoverflow.com/questions/2479784/exporting-static-data-in-a-dll

而有人回應如下:

The static member is not accessed directly by code in the calling application, only through member functions of the class in the dll. However there are several inline functions accessing the static member. Those functions will be inline expanded into the calling applications code makeing the calling application access the static member directly. That will violate the finding referenced above that static variables are local to the dll and cannot be referenced from the calling application.

而我也有找到另一個回文:
You can not export data fields from a DLL. You can only export functions!
The reason is simple. The binding mechanism for function to a DLL have a jump table where the final reference from the DLL is set into.Because the load address is unknown it is not possible to unreference a variable in a DLL.
Write a function that returns that static value!

從這兩個回文來看應該是說 dll 裡的 static 變數不能直接去 access 它,但還是不太瞭解它的原理,不知是否有哪位大大能幫小弟解惑一下,謝謝!
作者 : hgffly(飛) 貼文超過200則人氣指數超過10000點
[ 貼文 246 | 人氣 23261 | 評價 290 | 評價/貼文 1.18 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/10/24 上午 08:20:21
不好意思,想針對這原本的問題再提出後來遇到的另一個問題,就是我的 CA 之前原本和 Dialog 是在同一個專案下,
後來我將 CA 和 Dialog 這兩個分在兩個不同的專案,CA是 dll 專案,在 vc2010 編譯時,還是會出現同樣的問題
即如果 Dialog 這檔案有用到 CA 的 num 就會出現錯誤,假如只有 CA 本身的專案用到這變數則不會有錯誤,
我後來有去網路發現也有人遇到和我一樣的問題,原文請參考下列網址:
http://stackoverflow.com/questions/2479784/exporting-static-data-in-a-dll

而有人回應如下:

The static member is not accessed directly by code in the calling application, only through member functions of the class in the dll. However there are several inline functions accessing the static member. Those functions will be inline expanded into the calling applications code makeing the calling application access the static member directly. That will violate the finding referenced above that static variables are local to the dll and cannot be referenced from the calling application.

而我也有找到另一個回文:
You can not export data fields from a DLL. You can only export functions!
The reason is simple. The binding mechanism for function to a DLL have a jump table where the final reference from the DLL is set into.Because the load address is unknown it is not possible to unreference a variable in a DLL.
Write a function that returns that static value!

從這兩個回文來看應該是說 dll 裡的 static 變數不能直接去 access 它,但還是不太瞭解它的原理,不知是否有哪位大大能幫小弟解惑一下,謝謝!
作者 : ozzy123(ozzy) VC++優秀好手資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4498 | 人氣 37262 | 評價 11100 | 評價/貼文 2.47 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/8 下午 06:57:24
dll 裡的 static 變數不能直接去 access 它,
>> basically, a static variable in dll file and its scope is global but its life time is file scope. So it can be accessed by other files.
So you must declare it as a public variable . then it can be access in anywhere.
作者 : ozzy123(ozzy) VC++優秀好手資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4498 | 人氣 37262 | 評價 11100 | 評價/貼文 2.47 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/10 上午 10:53:33
an explain for you reference - http://realchecko.blogspot.tw/2007/07/share-data-in-dll.html
作者 : cheg(cheg)
[ 貼文 99 | 人氣 125 | 評價 410 | 評價/貼文 4.14 | 送出評價 24 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/10 下午 12:19:58
>
>http://stackoverflow.com/questions/2479784/exporting-static-data-in-a-dll
>
>而有人回應如下:
>
>The static member is not accessed directly by code in the calling application, only through member functions of the class in the dll. However there are several inline functions accessing the static member. Those functions will be inline expanded into the calling applications code makeing the calling application access the static member directly. That will violate the finding referenced above that static variables are local to the dll and cannot be referenced from the calling application.
>

這段是說,他寫的 dll 有些有 inline 函數去使用那個 static variable
那麼在用戶端引用 .h 的時候就會嘗試去連結那個變數。當然啦,你的
變數定義在 dll 的某個 c 裡面,執行檔無法連結到,就會出錯。

>而我也有找到另一個回文:
>You can not export data fields from a DLL. You can only export functions!
>The reason is simple. The binding mechanism for function to a DLL have a jump table where the final reference from the DLL is set into.Because the load address is unknown it is not possible to unreference a variable in a DLL.
>Write a function that returns that static value!
>

這段是說,對於函數 dll 都是把它放在一個 jump table (import address table)
在 loader 載入 dll 的時候會去修正這個表格中的含數位址,而 variable 沒這個機制 (...嗎?)
所以不能輸出變數

>從這兩個回文來看應該是說 dll 裡的 static 變數不能直接去 access 它,但還是不太瞭解它的原理,不知是否有哪位大大能幫小弟解惑一下,謝謝!
>
 板主 : 青衫 , Raymond
 > Visual C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - Visual C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
Visual C++
1 青衫 11070 
2 Raymond 10090 
3 Clier 7630 
4 小約翰 2500 
5 Cog 2030 
6 coco 1870 
7 aming 1410 
8 牧童哥 1400 
9 r2109 1380 
10 Akira 1350 
Visual C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.171875