寫C的時候需要調用之前的一個C程序,想用動態鏈接庫的方式。Mac下的動態鏈接庫是dylib,與Linux下的.os或Windows下的.dll不同。由於之前沒有接觸過,所以翻了大量的博客,然而在編譯過程中一路error。。。還是沒能解決問題。最后看了蘋果官方的關於動態鏈接庫的介紹https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html#//apple_ref/doc/uid/TP40001908-SW1,終於順利通過了。原文是英文文檔,建議大家看看,不想看的也可以看我的博客內容。
下面簡要說一下我的具體做法。
C生成動態鏈接庫
假設你之前有一個function.c,我們現在需要調用它,先把它做成一個動態鏈接庫。我是直接把這里面的main函數改了一下名字為enmain:
/*file: function.c*/
......
void enmain() {
fun1();
fun2();
...
}
在與function.c的同目錄下新建一個function.h文件,里面就是對你要調用的函數的申明。因為我是需要調用function整個程序,所以只要申明enmain這個函數部分:
/*file: function.h*/
void enmain();
這時候.h文件就寫好了,我們需要回過來對之前的function.c文件做一些修改補充:
- 頭文件加上
/*file: function.c*/
#include"function.h" //注意是用引號
#define EXPORT __attribute__((visibility("default"))) //具體原因可以看蘋果官方的解釋,我上面有貼鏈接
- 在需要調用的函數前面加一行EXPORT
/*file: function.c*/
EXPORT
void enmain() {
fun1();
fun2();
...
}
都修改好后,我們開始編譯。在終端輸入如下語句:
clang -dynamiclib -std=gnu99 function.c -current_version 1.0 -compatibility_version 1.0 -fvisibility=hidden -o libfunction.A.dylib
然后在與function.c的同目錄下會出現一個libfunction.A.dylib。至此,動態鏈接庫已經生成完畢。
C調用動態鏈接庫
假設我寫了一個程序test.c需要調用剛剛的function動態鏈接庫。由於我這個例子里面只導出了一個函數就是enmain(),實際操作的時候,可以導出.c文件中的多個函數。
- 頭文件加上
/*file: test.c*/
#include"function.h"
- 在需要用到enmain()的時候,就像標准庫函數一樣正常使用:
/*file: test.c*/
enmain();
然后編譯:
clang test.c libfunction.A.dylib -o test
運行:
./test
注意:
之前我寫的function是.cpp文件,在將其編譯為dylib時出現錯誤:
error: invalid argument '-std=gnu99' not allowed with 'C++/ObjC++'
所以后來改寫為純C就通過了。現在還不知道C++應該如何。。。
