今天遇到一個問題,在利用xxx.so庫鏈接成可執行文件的時候,xxx.so有好幾個函數符號一直報"undefined reference "的錯誤,仔細檢測了很多遍,那幾個函數確實是申明且定義了的。折騰一下午,后面發現這些函數被定義了成了inline函數,其實看到inline函數的時候也并沒有想到是這個錯誤,只是試探性的把它去掉之后,臥槽,這個錯誤竟然消失了。
發現錯誤之后仔細想了一下,inline函數在調用的地方是直接展開的,這個過程在程序編譯的時候就完成了,所以在鏈接的時候在符號表里就不存在inline函數的符號索引了,當然就會報這個錯誤了。
所以解決這個問題主要就是需要在預編譯階段把調用的地方的inline函數全部展開,所以inline函數得寫在頭文件里而不是源文件里。
舉例,有一個類HELLO中實現了一個inline函數print(),然后在main.cpp文件中試圖使用HELLO中的inline函數,那么在編譯生成main可執行文件的時候則會報"main.cpp:(.text+0xe9): undefined reference to `HELLO::print()'"錯誤:
#ifndef HELLO_H_
#define HELLO_H_
#include<string>
#include<iostream>
class HELLO
{
public:
HELLO();
explicit HELLO(std::string str);
void print();
private:
std::string _str;
};
#endif
#include "hello.hpp"
HELLO::HELLO()
{
_str = "WORLD";
}
HELLO::HELLO(std::string str)
{
_str = str;
}
inline void HELLO::print()
{
std::cout << _str << std::endl;
}
#include "hello.hpp"
int main()
{
HELLO hello("hello");
HELLO world("world");
hello.print();
world.print();
return 0;
}
把上面的inline函數print寫在頭文件中這不會有任何問題。