Mac下將C程序創建為動態鏈接庫再由另一個C程序調用


寫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++應該如何。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM