以古论今 發表於 2023-8-24 00:00:00

Linux静态库与动态库实例详解

<p>
        <strong>Linux静态库与动态库实例详解</strong></p>
<p>
        1. Linux 下静态链接库编译与使用</p>
<p>
        首先编写如下代码:</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_118392">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                        <div class="line number8 index7 alt1">
                                                                8</div>
                                                        <div class="line number9 index8 alt2">
                                                                9</div>
                                                        <div class="line number10 index9 alt1">
                                                                10</div>
                                                        <div class="line number11 index10 alt2">
                                                                11</div>
                                                        <div class="line number12 index11 alt1">
                                                                12</div>
                                                        <div class="line number13 index12 alt2">
                                                                13</div>
                                                        <div class="line number14 index13 alt1">
                                                                14</div>
                                                        <div class="line number15 index14 alt2">
                                                                15</div>
                                                        <div class="line number16 index15 alt1">
                                                                16</div>
                                                        <div class="line number17 index16 alt2">
                                                                17</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash plain">//</code> <code class="bash plain">main.c</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="bash comments">#include "test.h"</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                        <code class="bash plain">int main(){</code>
</div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="bash spaces">  </code><code class="bash functions">test</code><code class="bash plain">();</code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                        <code class="bash spaces">  </code><code class="bash keyword">return</code> <code class="bash plain">0;  </code>
</div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="bash plain">}</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                         </div>
                                                                <div class="line number8 index7 alt1">
                                                                        <code class="bash plain">//</code> <code class="bash functions">test</code><code class="bash plain">.h</code>
</div>
                                                                <div class="line number9 index8 alt2">
                                                                        <code class="bash comments">#include&lt;iostream&gt;</code>
</div>
                                                                <div class="line number10 index9 alt1">
                                                                        <code class="bash plain">using namespace std;</code>
</div>
                                                                <div class="line number11 index10 alt2">
                                                                        <code class="bash plain">void </code><code class="bash functions">test</code><code class="bash plain">();</code>
</div>
                                                                <div class="line number12 index11 alt1">
                                                                         </div>
                                                                <div class="line number13 index12 alt2">
                                                                        <code class="bash plain">//</code> <code class="bash functions">test</code><code class="bash plain">.c</code>
</div>
                                                                <div class="line number14 index13 alt1">
                                                                        <code class="bash comments">#include "test.h"</code>
</div>
                                                                <div class="line number15 index14 alt2">
                                                                        <code class="bash plain">void </code><code class="bash functions">test</code><code class="bash plain">(){</code>
</div>
                                                                <div class="line number16 index15 alt1">
                                                                        <code class="bash spaces"> </code><code class="bash plain">cout&lt;&lt; </code><code class="bash string">"test!"</code> <code class="bash plain">&lt;&lt;endl;</code>
</div>
                                                                <div class="line number17 index16 alt2">
                                                                        <code class="bash plain">}</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        然后编译:</p>
<p>
        1. gcc -c test.c //生成目标文件<br>
        2. ar crv libtest.a test.o //生成静态链接库libtest.a<br>
        3. g++ -o main main.c -ltest //编译main程序同时链接libtest.a静态库<br>
        4. ./main //运行main程序</p>
<p>
        2. Linux 下动态链接库编译与使用</p>
<p>
        代码与上述一致。</p>
<p>
        然后编译:</p>
<p>
        1. g++ -fPIC -shared -o libtest.so test.c //生成动态链接库libtest.so<br>
        2. g++ -o main main.c -ltest //调用动态链接库libtest.so<br>
        3. ./main //运行main程序</p>
<p>
        3. 链接时缺失了相关目标文件(.o)</p>
<p>
        代码与上述一致。</p>
<p>
        编译过程如下:</p>
<p>
        1. gcc -c test.c<br>
        2. gcc -c main.c<br>
        3. gcc -o main main.o</p>
<p>
        这时,你会发现,报错了:undefined reference to `test'.</p>
<p>
        这就是最典型的 undefined reference 错误,因为在链接时发现找不到某个函数的实现文件, 本例中test.o文件中包含了test()函数的实现,所以如果按下面这种方式链接就没事了。</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_134964">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash plain">1. gcc -o main main.o </code><code class="bash functions">test</code><code class="bash plain">.o</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_252274">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                        <div class="line number8 index7 alt1">
                                                                8</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash plain">【扩展】:其实上面为了让大家更加清楚底层原因,我把编译链接分开了,下面这样编译</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="bash plain">也会报undefined reference错,其实底层原因与上面是一样的。</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                         </div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="bash plain">gcc -o main main.c </code><code class="bash plain">//</code><code class="bash plain">缺少</code><code class="bash functions">test</code><code class="bash plain">()的实现文件 </code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                         </div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="bash plain">需要改成如下形式才能成功,将</code><code class="bash functions">test</code><code class="bash plain">()函数的实现文件一起编译。</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                         </div>
                                                                <div class="line number8 index7 alt1">
                                                                        <code class="bash plain">gcc -o main main.c </code><code class="bash functions">test</code><code class="bash plain">.c </code><code class="bash plain">//ok</code><code class="bash plain">,没问题了</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        4. 链接时缺少相关的库文件(.a/.so)</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_274133">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                        <div class="line number8 index7 alt1">
                                                                8</div>
                                                        <div class="line number9 index8 alt2">
                                                                9</div>
                                                        <div class="line number10 index9 alt1">
                                                                10</div>
                                                        <div class="line number11 index10 alt2">
                                                                11</div>
                                                        <div class="line number12 index11 alt1">
                                                                12</div>
                                                        <div class="line number13 index12 alt2">
                                                                13</div>
                                                        <div class="line number14 index13 alt1">
                                                                14</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash plain">在此,只举个静态库的例子,假设源码与上述一致。</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                         </div>
                                                                <div class="line number3 index2 alt2">
                                                                        <code class="bash plain">1. 把</code><code class="bash functions">test</code><code class="bash plain">.c编译成静态库:</code>
</div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="bash spaces">  </code><code class="bash plain">gcc -c </code><code class="bash functions">test</code><code class="bash plain">.c</code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                        <code class="bash spaces">  </code><code class="bash plain">sr -rc </code><code class="bash functions">test</code><code class="bash plain">.a </code><code class="bash functions">test</code><code class="bash plain">.o</code>
</div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="bash spaces">  </code><code class="bash plain">gcc -c main.c</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                         </div>
                                                                <div class="line number8 index7 alt1">
                                                                        <code class="bash plain">2. 生成可执行程序:</code>
</div>
                                                                <div class="line number9 index8 alt2">
                                                                        <code class="bash spaces">  </code><code class="bash plain">gcc -o main -main.o</code>
</div>
                                                                <div class="line number10 index9 alt1">
                                                                         </div>
                                                                <div class="line number11 index10 alt2">
                                                                        <code class="bash spaces">    </code><code class="bash plain">此时同样出现 undefined reference to `</code><code class="bash functions">test</code><code class="bash plain">'报错。其根本原因也是找不到</code><code class="bash functions">test</code><code class="bash plain">()函数的实现文</code>
</div>
                                                                <div class="line number12 index11 alt1">
                                                                        <code class="bash spaces">  </code><code class="bash plain">件,由于该</code><code class="bash functions">test</code><code class="bash plain">()函数的实现在</code><code class="bash functions">test</code><code class="bash plain">.a这个静态库中的,故在链接的时候需要在其后加入</code><code class="bash functions">test</code><code class="bash plain">.a这个</code>
</div>
                                                                <div class="line number13 index12 alt2">
                                                                        <code class="bash spaces">  </code><code class="bash plain">库,链接命令修改为如下形式即可。</code>
</div>
                                                                <div class="line number14 index13 alt1">
                                                                        <code class="bash spaces">  </code><code class="bash plain">1. gcc -o main main.c .</code><code class="bash plain">/test</code><code class="bash plain">.a</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        5. 多个库文件链接顺序问题</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_328646">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                        <div class="line number8 index7 alt1">
                                                                8</div>
                                                        <div class="line number9 index8 alt2">
                                                                9</div>
                                                        <div class="line number10 index9 alt1">
                                                                10</div>
                                                        <div class="line number11 index10 alt2">
                                                                11</div>
                                                        <div class="line number12 index11 alt1">
                                                                12</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash plain">这种问题也非常的隐蔽,不仔细研究你可能会感到非常地莫名其妙。我们依然回到第3小节所讨论</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="bash plain">的问题中,在最后,如果我们把链接的库的顺序换一下,看看会发生什么结果?</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                         </div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="bash plain">1. gcc -o main main.o func.a </code><code class="bash functions">test</code><code class="bash plain">.a</code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                         </div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="bash plain">我们会得到如下的编译错误:</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                         </div>
                                                                <div class="line number8 index7 alt1">
                                                                        <code class="bash plain">1. </code><code class="bash functions">test</code><code class="bash plain">.a(</code><code class="bash functions">test</code><code class="bash plain">.o): In </code><code class="bash keyword">function</code> <code class="bash plain">`</code><code class="bash functions">test</code><code class="bash plain">': </code>
</div>
                                                                <div class="line number9 index8 alt2">
                                                                        <code class="bash plain">2. </code><code class="bash functions">test</code><code class="bash plain">.c:(.text+0x13): undefined reference to `func' </code>
</div>
                                                                <div class="line number10 index9 alt1">
                                                                        <code class="bash plain">3. collect2: ld returned 1 </code><code class="bash functions">exit</code> <code class="bash plain">status </code>
</div>
                                                                <div class="line number11 index10 alt2">
                                                                        <code class="bash plain">因此,我们需要注意,在链接命令中给出所依赖的库时,需要注意库之间的依赖顺序,依赖其他库</code>
</div>
                                                                <div class="line number12 index11 alt1">
                                                                        <code class="bash plain">的库一定要放到被依赖库的前面,这样才能真正避免undefined reference的错误,完成编译链接。</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!</p>
<p>
        原文链接:http://blog.csdn.net/u013709270/article/details/53264141</p>
頁: [1]
查看完整版本: Linux静态库与动态库实例详解