C呼叫動態庫,windows linux

2021-08-03 17:38:44 字數 3074 閱讀 6870

i. windows平台下c呼叫動態庫的方法:

case 1:如果提供了.lib和.dll,則不需要動態載入,因為動態庫的.lib中含有dll的所有匯出符號

(參考:俞甲子等. 《程式設計師的自我修養》)

1、假設動態庫的原始檔math.c包含乙個add函式,被宣告為匯出函式(可被庫外部呼叫):

extern "c" __declspec(dllexport) double add(double a, double b)/**

*  extern 表示這是個全域性函式,可以供各個其他的函式呼叫,其實extern沒有意義,因為全域性函式本來就可以被外部訪問。

* 「c」 表示編譯時按照 c編譯器的方式進行編譯,而不是c++。 c++的編譯方式考慮了函式過載,所以對函式名進行了新的修飾,產生了所謂的破壞性命名。

/*編譯成動態庫:cl /ldd(或者/ld,d代表debug版) math.c

編譯生成了math.dll, math.obj, math.exp, math.lib四個檔案

2、使用dll

/* test..c*/

#include

__declspec(dllimprot) double add(double, double); //宣告這個要用的匯入函式

int main(int argc, char **argv)

編譯專案**:cl /c  test.c

鏈結動態庫: link test.obj math.lib

完成生成test.exe

case 1:如果僅有.dll,需要顯示執行時載入(即loadlibrary(), getprocaddress()那一套)

假設還是剛才那個math.dll,依舊要使用那個定義為匯出函式(即__declspec(dllexport))的add函式

#include

#include

typedef double (*func)(double, double);//宣告出指向dll目標函式的函式指標

int main(int argc, char **argv)

// get func address

function = (func)getprocaddress(hinstlib, "add");

if(function == null)

// call it

int res = function(3.0,3.0);

freelibrary(hinstlib);

return 0; }

ii. linux平台下c呼叫共享庫(.so)的方法:

case1. 有同時提供.h檔案和.so檔案

1. 編寫foo庫

/* foo.h*/

#ifndef foo_h__

#define foo_h__

extern void foo(void);

#endif  // foo_h__

/* foo.c*/

#include

void foo(void)

2.製作foo.so庫

$gcc -c -wall -werror -fpic foo.c -o foo.o

$gcc -shared -o libfoo.so foo.o

3. **main.c:

#include

#include "foo.h" //有.h可用

int main(void)

4. 在編譯時鏈結動態庫:

$gcc -l/home/username/foo -wall -o test main.c -lfoo

5. 執行

$export ld_library_path=/home/username/foo:$ld_library_path    #新增動態庫搜尋路徑,因為test的執行需要依賴foo庫

$./test

case2. 僅有.so檔案,可以執行時動態載入

#include

#include

int main(int argc, char* argv)

// address the func foo

func = dlsym(handle, "foo");

if( (error=dlerror()) !=null)

//call it

foo();

return 0; }

編譯:$gcc -o test test.c -ldl  #-ldl代表鏈結用於支援動態載入庫的動態鏈結庫(dl庫)

執行:./test

#可以看出執行時載入的方式 不需要 在編譯、執行時指明要用的庫(共享物件),只需鏈結dl庫幷包含dlfcn.h,用於支援dlopen, dlsym這一套機制。

只有.so,也可以在鏈結階段鏈結.so,本檔案中通過宣告外部函式來訪問

**檔案:

**main.c:

#include

//無.h可用

//宣告外部函式

extern void foo(void);

int main(void)

$gcc test.c libfoo.so -o main  xlinker -rpath ./ #後面幾個引數為鏈結器指明.so的查詢路徑

C呼叫C 動態庫,靜態庫

c呼叫c 動態庫,靜態庫 1 include 2 using namespace std 34 class paul 5 10 11 int paul add int a,int b 12 17 18 extern c 如果沒有則不行 19 25 1 include 2 extern void ca...

VC 呼叫C 動態庫

近期專案中,需要訪問客戶資料庫,客戶不希望直接訪問其資料庫,而是以動態庫介面的形式開放,還是用c 開發的。經過不斷嘗試,總結方法如下 包含動態庫 using test.dll using namespace test lib using namespace runtime interopservic...

Lua Lua呼叫C動態庫

lua 好歸好,但有很多對效率要求較高的服務,還得讓c來完成。本篇學習下lua如何呼叫c。最重要的部分 定義乙個 luaopen 函式,並呼叫 lual openlib 函式 int luaopen mylib lua state l key val,相當於 必不可少 lual newlib l,l...