c++中調用 c靜態函數庫的方法

此文參考了網友前輩的《extern "C"用法》一文,在此附上鍊接表示對前輩的尊敬
http://www.jianshu.com/p/5d2eeeb93590

首先,編寫靜態庫函數

/* player.h */
#ifndef __PLAYER_H
#define __PLAYER_H
void player_open(char * path);
 
#endif
/* player.c */
#include "player.h"
#include <stdio.h>
 
void player_open(char * path)
{
printf("you select file : %s",path);
}
然後,編譯成目標文件
[root@MiWiFi-R1CM-srv lllll]# gcc -c player.c -o player.o
[root@MiWiFi-R1CM-srv lllll]# ls
main.cpp player.c player.h player.o
再然後,打包成靜態庫
[root@MiWiFi-R1CM-srv lllll]# ar cqs libplayer.a player.o
[root@MiWiFi-R1CM-srv lllll]# ls
libplayer.a main.cpp player.c player.h player.o
準備c++測試文件
#include <iostream>
 
extern "C"
{
#include "player.h"
}
 
using namespace::std;
 
int main(int argc, char ** argv)
{
player_open(argv[1]);
cout<<"you input : "<<argv[1]<<endl;
return 0;
}
最後,編譯連接
[root@MiWiFi-R1CM-srv lllll]# g++ main.cpp -L. -lplayer -o main
[root@MiWiFi-R1CM-srv lllll]# ls
libplayer.a main main.cpp player.c player.h player.o
[root@MiWiFi-R1CM-srv lllll]# ./main ahgkfhaeua
you select file : ahgkfhaeuayou input : ahgkfhaeua
編譯的時候 main.cpp 要寫在 -Ljjj -ljjj 前邊,如果寫在後邊的話就會報錯(不知爲何)
[root@MiWiFi-R1CM-srv lllll]# g++ -L. -lplayer main.cpp -o main
/tmp/cc6bn6N5.o: In function `main':
main.cpp:(.text+0x92): undefined reference to `player_open'
collect2: ld 返回 1
總結:
    c++ 要調用c寫成的共享庫函數時 要注意在c++文件包含c頭文件的時候要寫在 extern "C"{} 裏邊,因爲不同編譯器解釋函數名時並不一樣
    下面用nm命令看一下gcc 和g++ 編譯出來的庫中符號的區別
/* g++ -c player.c -o player.o*/
[root@MiWiFi-R1CM-srv lllll]# nm libplayer.a
 
player.o:
00000018 T _Z11player_openPc
00000006 T _Z11player_stopv
00000000 T _Z12player_pausev
00000012 T _Z16player_setVolumei
0000000c T _Z18player_setSchedulei
U __gxx_personality_v0
U printf
[root@MiWiFi-R1CM-srv lllll]# nm libplayerc.a
 
player.o:
00000000 T player_open
0000001b T player_pause
00000025 T player_setSchedule
0000002a T player_setVolume
00000020 T player_stop
U printf
注意 c函數名 play_open  經c++編譯後成了 _Z11player_openPc
extern “C”的作用就是 告訴編譯器 此段代碼用C編譯器解釋


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章