真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

c語(yǔ)言指定靜態(tài)庫(kù)的函數(shù) c語(yǔ)言靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的建立

C語(yǔ)言庫(kù)函數(shù)

假定你是在linux下做這件事 (在windows下應(yīng)該也是類似的)

站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到謝家集網(wǎng)站設(shè)計(jì)與謝家集網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、主機(jī)域名網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋謝家集地區(qū)。

假定你要產(chǎn)生的庫(kù)名字為 libtest.a

1. 實(shí)現(xiàn)庫(kù)函數(shù)于 test.c

#include stdio.h

int test()

{

printf("hello world!\n");

return 0;

}

test.h內(nèi)容:

extern int test();

2. 編譯test.c并產(chǎn)生庫(kù)文件

gcc -c test.c

ar -r libtest.a test.o

3. 其他程序如何調(diào)用 libtest.a 里的 test()函數(shù)?

main.c

#include "test.h"

int main()

{

return test();

}

4. 編譯main.c產(chǎn)生可執(zhí)行文件

gcc -o main.out main.c -L/path/to/libtest -ltest

5. 運(yùn)行 main.out

./main.out

PS, 頭文件的用處無(wú)非就是提供函數(shù)原型聲明,在我上面給的例子中,可以把 test.h 刪除, 但是必須在 main.c 里自己加上 extern int test(); 來(lái)聲明函數(shù)。

關(guān)于c/c++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別

靜態(tài)庫(kù)

之所以成為【靜態(tài)庫(kù)】,是因?yàn)樵阪溄与A段,會(huì)將匯編生成的目標(biāo)文件.o與引用到的庫(kù)一起鏈接打包到可執(zhí)行文件中。因此對(duì)應(yīng)的鏈接方式稱為靜態(tài)鏈接。

試想一下,靜態(tài)庫(kù)與匯編生成的目標(biāo)文件一起鏈接為可執(zhí)行文件,那么靜態(tài)庫(kù)必定跟.o文件格式相似。其實(shí)一個(gè)靜態(tài)庫(kù)可以簡(jiǎn)單看成是一組目標(biāo)文件(.o/.obj文件)的集合,即很多目標(biāo)文件經(jīng)過(guò)壓縮打包后形成的一個(gè)文件。靜態(tài)庫(kù)特點(diǎn)總結(jié):

l 靜態(tài)庫(kù)對(duì)函數(shù)庫(kù)的鏈接是放在編譯時(shí)期完成的。

l 程序在運(yùn)行時(shí)與函數(shù)庫(kù)再無(wú)瓜葛,移植方便。

l 浪費(fèi)空間和資源,因?yàn)樗邢嚓P(guān)的目標(biāo)文件與牽涉到的函數(shù)庫(kù)被鏈接合成一個(gè)可執(zhí)行文件。

下面編寫一些簡(jiǎn)單的四則運(yùn)算C++類,將其編譯成靜態(tài)庫(kù)給他人用,頭文件如下所示:

StaticMath.h頭文件

#pragma once

class StaticMath

{

public:

StaticMath(void);

~StaticMath(void);

static double add(double a, double b);//加法

static double sub(double a, double b);//減法

static double mul(double a, double b);//乘法

static double div(double a, double b);//除法

void print();

};

Linux下使用ar工具、Windows下vs使用lib.exe,將目標(biāo)文件壓縮到一起,并且對(duì)其進(jìn)行編號(hào)和索引,以便于查找和檢索。一般創(chuàng)建靜態(tài)庫(kù)的步驟如圖所示:

圖:創(chuàng)建靜態(tài)庫(kù)過(guò)程

Linux下創(chuàng)建與使用靜態(tài)庫(kù)

Linux靜態(tài)庫(kù)命名規(guī)則

Linux靜態(tài)庫(kù)命名規(guī)范,必須是"lib[your_library_name].a":lib為前綴,中間是靜態(tài)庫(kù)名,擴(kuò)展名為.a。

創(chuàng)建靜態(tài)庫(kù)(.a)

通過(guò)上面的流程可以知道,Linux創(chuàng)建靜態(tài)庫(kù)過(guò)程如下:

l 首先,將代碼文件編譯成目標(biāo)文件.o(StaticMath.o)

g++ -c StaticMath.cpp

注意帶參數(shù)-c,否則直接編譯為可執(zhí)行文件

l 然后,通過(guò)ar工具將目標(biāo)文件打包成.a靜態(tài)庫(kù)文件

ar -crv libstaticmath.a StaticMath.o

生成靜態(tài)庫(kù)libstaticmath.a。

大一點(diǎn)的項(xiàng)目會(huì)編寫makefile文件(CMake等等工程管理工具)來(lái)生成靜態(tài)庫(kù),輸入多個(gè)命令太麻煩了。

使用靜態(tài)庫(kù)

編寫使用上面創(chuàng)建的靜態(tài)庫(kù)的測(cè)試代碼:

測(cè)試代碼:

#include "StaticMath.h"

#include iostream

using namespace std;

int main(int argc, char* argv[])

{

double a = 10;

double b = 2;

cout "a + b = " StaticMath::add(a,

b) endl;

cout "a - b = " StaticMath::sub(a,

b) endl;

cout "a * b = " StaticMath::mul(a,

b) endl;

cout "a / b = " StaticMath::div(a,

b) endl;

StaticMath sm;

sm.print();

system("pause");

return 0;

}

Linux下使用靜態(tài)庫(kù),只需要在編譯的時(shí)候,指定靜態(tài)庫(kù)的搜索路徑(-L選項(xiàng))、指定靜態(tài)庫(kù)名(不需要lib前綴和.a后綴,-l選項(xiàng))。

# g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath

l -L:表示要連接的庫(kù)所在目錄

l -l:指定鏈接時(shí)需要的動(dòng)態(tài)庫(kù),編譯器查找動(dòng)態(tài)連接庫(kù)時(shí)有隱含的命名規(guī)則,即在給出的名字前面加上lib,后面加上.a或.so來(lái)確定庫(kù)的名稱。

Windows下創(chuàng)建與使用靜態(tài)庫(kù)

創(chuàng)建靜態(tài)庫(kù)(.lib)

如果是使用VS命令行生成靜態(tài)庫(kù),也是分兩個(gè)步驟來(lái)生成程序:

l 首先,通過(guò)使用帶編譯器選項(xiàng) /c 的 Cl.exe 編譯代碼 (cl

/c StaticMath.cpp),創(chuàng)建名為“StaticMath.obj”的目標(biāo)文件。

l 然后,使用庫(kù)管理器 Lib.exe 鏈接代碼 (lib StaticMath.obj),創(chuàng)建靜態(tài)庫(kù)StaticMath.lib。

當(dāng)然,我們一般不這么用,使用VS工程設(shè)置更方便。創(chuàng)建win32控制臺(tái)程序時(shí),勾選靜態(tài)庫(kù)類型;打開(kāi)工程“屬性面板”è”配置屬性”è”常規(guī)”,配置類型選擇靜態(tài)庫(kù)。

圖:vs靜態(tài)庫(kù)項(xiàng)目屬性設(shè)置

Build項(xiàng)目即可生成靜態(tài)庫(kù)。

使用靜態(tài)庫(kù)

測(cè)試代碼Linux下面的一樣。有3種使用方法:

方法一:

在VS中使用靜態(tài)庫(kù)方法:

l 工程“屬性面板”è“通用屬性”è “框架和引用”è”添加引用”,將顯示“添加引用”對(duì)話框。 “項(xiàng)目”選項(xiàng)卡列出了當(dāng)前解決方案中的各個(gè)項(xiàng)目以及可以引用的所有庫(kù)。 在“項(xiàng)目”選項(xiàng)卡中,選擇 StaticLibrary。 單擊“確定”。

l 添加StaticMath.h 頭文件目錄,必須修改包含目錄路徑。打開(kāi)工程“屬性面板”è”配置屬性”è “C/C++”è” 常規(guī)”,在“附加包含目錄”屬性值中,鍵入StaticMath.h 頭文件所在目錄的路徑或?yàn)g覽至該目錄。

編譯運(yùn)行OK。

圖:靜態(tài)庫(kù)測(cè)試結(jié)果(vs)

如果引用的靜態(tài)庫(kù)不是在同一解決方案下的子工程,而是使用第三方提供的靜態(tài)庫(kù)lib和頭文件,上面的方法設(shè)置不了。還有2中方法設(shè)置都可行。

方法二:

打開(kāi)工程“屬性面板”è”配置屬性”è “鏈接器”è”命令行”,輸入靜態(tài)庫(kù)的完整路徑即可。

方法三:

l “屬性面板”è”配置屬性”è “鏈接器”è”常規(guī)”,附加依賴庫(kù)目錄中輸入,靜態(tài)庫(kù)所在目錄;

l “屬性面板”è”配置屬性”è “鏈接器”è”輸入”,附加依賴庫(kù)中輸入靜態(tài)庫(kù)名StaticLibrary.lib。

動(dòng)態(tài)庫(kù)

通過(guò)上面的介紹發(fā)現(xiàn)靜態(tài)庫(kù),容易使用和理解,也達(dá)到了代碼復(fù)用的目的,那為什么還需要?jiǎng)討B(tài)庫(kù)呢?

為什么還需要?jiǎng)討B(tài)庫(kù)?

為什么需要?jiǎng)討B(tài)庫(kù),其實(shí)也是靜態(tài)庫(kù)的特點(diǎn)導(dǎo)致。

l 空間浪費(fèi)是靜態(tài)庫(kù)的一個(gè)問(wèn)題。

l 另一個(gè)問(wèn)題是靜態(tài)庫(kù)對(duì)程序的更新、部署和發(fā)布頁(yè)會(huì)帶來(lái)麻煩。如果靜態(tài)庫(kù)liba.lib更新了,所以使用它的應(yīng)用程序都需要重新編譯、發(fā)布給用戶(對(duì)于玩家來(lái)說(shuō),可能是一個(gè)很小的改動(dòng),卻導(dǎo)致整個(gè)程序重新下載,全量更新)。

動(dòng)態(tài)庫(kù)在程序編譯時(shí)并不會(huì)被連接到目標(biāo)代碼中,而是在程序運(yùn)行是才被載入。不同的應(yīng)用程序如果調(diào)用相同的庫(kù),那么在內(nèi)存里只需要有一份該共享庫(kù)的實(shí)例,規(guī)避了空間浪費(fèi)問(wèn)題。動(dòng)態(tài)庫(kù)在程序運(yùn)行是才被載入,也解決了靜態(tài)庫(kù)對(duì)程序的更新、部署和發(fā)布頁(yè)會(huì)帶來(lái)麻煩。用戶只需要更新動(dòng)態(tài)庫(kù)即可,增量更新。

動(dòng)態(tài)庫(kù)特點(diǎn)總結(jié):

l 動(dòng)態(tài)庫(kù)把對(duì)一些庫(kù)函數(shù)的鏈接載入推遲到程序運(yùn)行的時(shí)期。

l 可以實(shí)現(xiàn)進(jìn)程之間的資源共享。(因此動(dòng)態(tài)庫(kù)也稱為共享庫(kù))

l 將一些程序升級(jí)變得簡(jiǎn)單。

l 甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制(顯示調(diào)用)。

Window與Linux執(zhí)行文件格式不同,在創(chuàng)建動(dòng)態(tài)庫(kù)的時(shí)候有一些差異。

l 在Windows系統(tǒng)下的執(zhí)行文件格式是PE格式,動(dòng)態(tài)庫(kù)需要一個(gè)DllMain函數(shù)做出初始化的入口,通常在導(dǎo)出函數(shù)的聲明時(shí)需要有_declspec(dllexport)關(guān)鍵字。

l Linux下gcc編譯的執(zhí)行文件默認(rèn)是ELF格式,不需要初始化入口,亦不需要函數(shù)做特別的聲明,編寫比較方便。

與創(chuàng)建靜態(tài)庫(kù)不同的是,不需要打包工具(ar、lib.exe),直接使用編譯器即可創(chuàng)建動(dòng)態(tài)庫(kù)。

Linux下創(chuàng)建與使用動(dòng)態(tài)庫(kù)

linux動(dòng)態(tài)庫(kù)的命名規(guī)則

動(dòng)態(tài)鏈接庫(kù)的名字形式為 libxxx.so,前綴是lib,后綴名為“.so”。

l 針對(duì)于實(shí)際庫(kù)文件,每個(gè)共享庫(kù)都有個(gè)特殊的名字“soname”。在程序啟動(dòng)后,程序通過(guò)這個(gè)名字來(lái)告訴動(dòng)態(tài)加載器該載入哪個(gè)共享庫(kù)。

l 在文件系統(tǒng)中,soname僅是一個(gè)鏈接到實(shí)際動(dòng)態(tài)庫(kù)的鏈接。對(duì)于動(dòng)態(tài)庫(kù)而言,每個(gè)庫(kù)實(shí)際上都有另一個(gè)名字給編譯器來(lái)用。它是一個(gè)指向?qū)嶋H庫(kù)鏡像文件的鏈接文件(lib+soname+.so)。

創(chuàng)建動(dòng)態(tài)庫(kù)(.so)

編寫四則運(yùn)算動(dòng)態(tài)庫(kù)代碼:

DynamicMath.h頭文件

#pragma once

class DynamicMath

{

public:

DynamicMath(void);

~DynamicMath(void);

static double add(double a, double b);//?ó·¨

static double sub(double a, double b);//??·¨

static double mul(double a, double b);//3?·¨

static double div(double a, double b);//3y·¨

void print();

};

l 首先,生成目標(biāo)文件,此時(shí)要加編譯器選項(xiàng)-fpic

g++ -fPIC -c DynamicMath.cpp

-fPIC 創(chuàng)建與地址無(wú)關(guān)的編譯程序(pic,position independent code),是為了能夠在多個(gè)應(yīng)用程序間共享。

l 然后,生成動(dòng)態(tài)庫(kù),此時(shí)要加鏈接器選項(xiàng)-shared

g++ -shared -o libdynmath.so DynamicMath.o

-shared指定生成動(dòng)態(tài)鏈接庫(kù)。

其實(shí)上面兩個(gè)步驟可以合并為一個(gè)命令:

g++ -fPIC -shared -o libdynmath.so DynamicMath.cpp

使用動(dòng)態(tài)庫(kù)

編寫使用動(dòng)態(tài)庫(kù)的測(cè)試代碼:

測(cè)試代碼:

#include "../DynamicLibrary/DynamicMath.h"

#include iostream

using namespace std;

int main(int argc, char* argv[])

{

double a = 10;

double b = 2;

cout "a + b = " DynamicMath::add(a, b) endl;

cout "a - b = " DynamicMath::sub(a, b) endl;

cout "a * b = " DynamicMath::mul(a, b) endl;

cout "a / b = " DynamicMath::div(a, b) endl;

DynamicMath dyn;

dyn.print();

return 0;

}

引用動(dòng)態(tài)庫(kù)編譯成可執(zhí)行文件(跟靜態(tài)庫(kù)方式一樣):

g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath

然后運(yùn)行:./a.out,發(fā)現(xiàn)竟然報(bào)錯(cuò)了!??!

可能大家會(huì)猜測(cè),是因?yàn)閯?dòng)態(tài)庫(kù)跟測(cè)試程序不是一個(gè)目錄,那我們驗(yàn)證下是否如此:

發(fā)現(xiàn)還是報(bào)錯(cuò)?。?!那么,在執(zhí)行的時(shí)候是如何定位共享庫(kù)文件的呢?

1) 當(dāng)系統(tǒng)加載可執(zhí)行代碼時(shí)候,能夠知道其所依賴的庫(kù)的名字,但是還需要知道絕對(duì)路徑。此時(shí)就需要系統(tǒng)動(dòng)態(tài)載入器(dynamic linker/loader)。

2) 對(duì)于elf格式的可執(zhí)行程序,是由ld-linux.so*來(lái)完成的,它先后搜索elf文件的DT_RPATH段—環(huán)境變量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 目錄找到庫(kù)文件后將其載入內(nèi)存。

如何讓系統(tǒng)能夠找到它:

l 如果安裝在/lib或者/usr/lib下,那么ld默認(rèn)能夠找到,無(wú)需其他操作。

l 如果安裝在其他目錄,需要將其添加到/etc/ld.so.cache文件中,步驟如下:

n 編輯/etc/ld.so.conf文件,加入庫(kù)文件所在目錄的路徑

n 運(yùn)行l(wèi)dconfig ,該命令會(huì)重建/etc/ld.so.cache文件

我們將創(chuàng)建的動(dòng)態(tài)庫(kù)復(fù)制到/usr/lib下面,然后運(yùn)行測(cè)試程序。

Windows下創(chuàng)建與使用動(dòng)態(tài)庫(kù)

創(chuàng)建動(dòng)態(tài)庫(kù)(.dll)

與Linux相比,在Windows系統(tǒng)下創(chuàng)建動(dòng)態(tài)庫(kù)要稍微麻煩一些。首先,需要一個(gè)DllMain函數(shù)做出初始化的入口(創(chuàng)建win32控制臺(tái)程序時(shí),勾選DLL類型會(huì)自動(dòng)生成這個(gè)文件):

dllmain.cpp入口文件

// dllmain.cpp : Defines the entry point for the DLL application.

#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

break;

}

return TRUE;

}

通常在導(dǎo)出函數(shù)的聲明時(shí)需要有_declspec(dllexport)關(guān)鍵字:

DynamicMath.h頭文件

#pragma once

class DynamicMath

{

public:

__declspec(dllexport) DynamicMath(void);

__declspec(dllexport) ~DynamicMath(void);

static __declspec(dllexport) double add(double a, double b);//加法

static __declspec(dllexport) double sub(double a, double b);//減法

static __declspec(dllexport) double mul(double a, double b);//乘法

static __declspec(dllexport) double div(double a, double b);//除法

__declspec(dllexport) void print();

};

生成動(dòng)態(tài)庫(kù)需要設(shè)置工程屬性,打開(kāi)工程“屬性面板”è”配置屬性”è”常規(guī)”,配置類型選擇動(dòng)態(tài)庫(kù)。

圖:v動(dòng)態(tài)庫(kù)項(xiàng)目屬性設(shè)置

Build項(xiàng)目即可生成動(dòng)態(tài)庫(kù)。

使用動(dòng)態(tài)庫(kù)

創(chuàng)建win32控制臺(tái)測(cè)試程序:

TestDynamicLibrary.cpp測(cè)試程序

#include "stdafx.h"

#include "DynamicMath.h"

#include iostream

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

double a = 10;

double b = 2;

cout "a + b = " DynamicMath::add(a,

b) endl;

cout "a - b = " DynamicMath::sub(a,

b) endl;

cout "a * b = " DynamicMath::mul(a,

b) endl;

cout "a / b = " DynamicMath::div(a,

b) endl;

DynamicMath dyn;

dyn.print();

system("pause");

return 0;

}

方法一:

l 工程“屬性面板”è“通用屬性”è “框架和引用”è”添加引用”,將顯示“添加引用”對(duì)話框?!绊?xiàng)目”選項(xiàng)卡列出了當(dāng)前解決方案中的各個(gè)項(xiàng)目以及可以引用的所有庫(kù)。 在“項(xiàng)目”選項(xiàng)卡中,選擇 DynamicLibrary。 單擊“確定”。

l 添加DynamicMath.h 頭文件目錄,必須修改包含目錄路徑。打開(kāi)工程“屬性面板”è”配置屬性”è “C/C++”è” 常規(guī)”,在“附加包含目錄”屬性值中,鍵入DynamicMath.h 頭文件所在目錄的路徑或?yàn)g覽至該目錄。

編譯運(yùn)行OK。

圖:動(dòng)態(tài)庫(kù)測(cè)試結(jié)果(vs)

方法二:

l “屬性面板”è”配置屬性”è “鏈接器”è”常規(guī)”,附加依賴庫(kù)目錄中輸入,動(dòng)態(tài)庫(kù)所在目錄;

l “屬性面板”è”配置屬性”è “鏈接器”è”輸入”,附加依賴庫(kù)中輸入動(dòng)態(tài)庫(kù)編譯出來(lái)的DynamicLibrary.lib。

這里可能大家有個(gè)疑問(wèn),動(dòng)態(tài)庫(kù)怎么還有一個(gè)DynamicLibrary.lib文件?即無(wú)論是靜態(tài)鏈接庫(kù)還是動(dòng)態(tài)鏈接庫(kù),最后都有l(wèi)ib文件,那么兩者區(qū)別是什么呢?其實(shí),兩個(gè)是完全不一樣的東西。

StaticLibrary.lib的大小為190KB,DynamicLibrary.lib的大小為3KB,靜態(tài)庫(kù)對(duì)應(yīng)的lib文件叫靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)對(duì)應(yīng)的lib文件叫【導(dǎo)入庫(kù)】。實(shí)際上靜態(tài)庫(kù)本身就包含了實(shí)際執(zhí)行代碼、符號(hào)表等等,而對(duì)于導(dǎo)入庫(kù)而言,其實(shí)際的執(zhí)行代碼位于動(dòng)態(tài)庫(kù)中,導(dǎo)入庫(kù)只包含了地址符號(hào)表等,確保程序找到對(duì)應(yīng)函數(shù)的一些基本地址信息。

動(dòng)態(tài)庫(kù)的顯式調(diào)用

上面介紹的動(dòng)態(tài)庫(kù)使用方法和靜態(tài)庫(kù)類似屬于隱式調(diào)用,編譯的時(shí)候指定相應(yīng)的庫(kù)和查找路徑。其實(shí),動(dòng)態(tài)庫(kù)還可以顯式調(diào)用?!驹贑語(yǔ)言中】,顯示調(diào)用一個(gè)動(dòng)態(tài)庫(kù)輕而易舉!

在Linux下顯式調(diào)用動(dòng)態(tài)庫(kù)

#include dlfcn.h,提供了下面幾個(gè)接口:

l void * dlopen( const char * pathname, int mode ):函數(shù)以指定模式打開(kāi)指定的動(dòng)態(tài)連接庫(kù)文件,并返回一個(gè)句柄給調(diào)用進(jìn)程。

l void* dlsym(void* handle,const char* symbol):dlsym根據(jù)動(dòng)態(tài)鏈接庫(kù)操作句柄(pHandle)與符號(hào)(symbol),返回符號(hào)對(duì)應(yīng)的地址。使用這個(gè)函數(shù)不但可以獲取函數(shù)地址,也可以獲取變量地址。

l int dlclose (void *handle):dlclose用于關(guān)閉指定句柄的動(dòng)態(tài)鏈接庫(kù),只有當(dāng)此動(dòng)態(tài)鏈接庫(kù)的使用計(jì)數(shù)為0時(shí),才會(huì)真正被系統(tǒng)卸載。

l const char *dlerror(void):當(dāng)動(dòng)態(tài)鏈接庫(kù)操作函數(shù)執(zhí)行失敗時(shí),dlerror可以返回出錯(cuò)信息,返回值為NULL時(shí)表示操作函數(shù)執(zhí)行成功。

在Windows下顯式調(diào)用動(dòng)態(tài)庫(kù)

應(yīng)用程序必須進(jìn)行函數(shù)調(diào)用以在運(yùn)行時(shí)顯式加載 DLL。為顯式鏈接到 DLL,應(yīng)用程序必須:

l 調(diào)用 LoadLibrary(或相似的函數(shù))以加載 DLL 和獲取模塊句柄。

l 調(diào)用 GetProcAddress,以獲取指向應(yīng)用程序要調(diào)用的每個(gè)導(dǎo)出函數(shù)的函數(shù)指針。由于應(yīng)用程序是通過(guò)指針調(diào)用 DLL 的函數(shù),編譯器不生成外部引用,故無(wú)需與導(dǎo)入庫(kù)鏈接。

l 使用完 DLL 后調(diào)用 FreeLibrary。

顯式調(diào)用C++動(dòng)態(tài)庫(kù)注意點(diǎn)

對(duì)C++來(lái)說(shuō),情況稍微復(fù)雜。顯式加載一個(gè)C++動(dòng)態(tài)庫(kù)的困難一部分是因?yàn)镃++的name

mangling;另一部分是因?yàn)闆](méi)有提供一個(gè)合適的API來(lái)裝載類,在C++中,您可能要用到庫(kù)中的一個(gè)類,而這需要?jiǎng)?chuàng)建該類的一個(gè)實(shí)例,這不容易做到。

name mangling可以通過(guò)extern "C"解決。C++有個(gè)特定的關(guān)鍵字用來(lái)聲明采用C

binding的函數(shù):extern "C" 。用 extern "C"聲明的函數(shù)將使用函數(shù)名作符號(hào)名,就像C函數(shù)一樣。因此,只有非成員函數(shù)才能被聲明為extern

"C",并且不能被重載。盡管限制多多,extern "C"函數(shù)還是非常有用,因?yàn)樗鼈兛梢韵驝函數(shù)一樣被dlopen動(dòng)態(tài)加載。冠以extern

"C"限定符后,并不意味著函數(shù)中無(wú)法使用C++代碼了,相反,它仍然是一個(gè)完全的C++函數(shù),可以使用任何C++特性和各種類型的參數(shù)。

C++怎么定義自己的庫(kù)函數(shù)

1。使用命令行tcc max.c mylib.lib一同編譯。mylib.lib需放在tc能找到的地方,什么是tc能找到的地方呢?一是tc的工作目錄,默認(rèn)是tc的安裝目錄,或者是你自己改動(dòng)的自定義目錄,對(duì)于tcc命令行,自定義工作目錄信息存放在turboc.cfg文件里;二是tc的系統(tǒng)目錄,比如lib目錄。mylib.h文件也是同樣道理。mylib.lib和mylib.h兩個(gè)文件最好都放在當(dāng)前工作目錄里,不要放進(jìn)inlucde和lib等系統(tǒng)目錄,免得搞混了。

2。建立一個(gè)工程文件,比如起個(gè)叫max.prj的文件,把max.c和mylib.lib一起寫進(jìn)去,然后編譯這個(gè)工程就可以了,mylib.lib和mylib.h兩個(gè)文件也是放在當(dāng)前工作目錄里。在IDE環(huán)境里,自定義工作目錄不是由turboc.cfg文件指定的,是由tcconfig.tc或其它你自己命名的配置文件指定的,改動(dòng)的方法在option-directory里面。

關(guān)于c語(yǔ)言中如何創(chuàng)建自己的庫(kù)函數(shù)能不能再詳細(xì)的解釋一下,謝謝了?。。?/h2>

哈哈,選我吧!庫(kù)分靜態(tài)庫(kù)和動(dòng)態(tài)鏈接庫(kù),靜態(tài)庫(kù)以lib結(jié)尾,被編譯器里的鏈接器識(shí)別。windows下動(dòng)態(tài)庫(kù)以dll結(jié)尾,被操作系統(tǒng)加載以模塊方式映射到進(jìn)程地址空間。一般初學(xué)者先學(xué)會(huì)創(chuàng)建的是靜態(tài)庫(kù)。靜態(tài)庫(kù)是一個(gè)無(wú)需重定位的函數(shù)集。怎么做到無(wú)需重定位呢?這是編譯器做的編譯工作,例如它指定開(kāi)頭的位置作為基址,剩下的代碼用到的都是相對(duì)偏移。這樣,這段二進(jìn)制代碼可以被放在內(nèi)存中的任何位置執(zhí)行,被寫入了lib文件里。在lib文件里,包含了函數(shù)名與函數(shù)地址組成的結(jié)構(gòu)體,通過(guò)它編譯器可以找到lib文件里需要的二進(jìn)制代碼并以靜態(tài)聯(lián)編的方式寫入我們調(diào)用它的exe文件里。這種代碼是被塞進(jìn)exe文件里而無(wú)需修改,并在程序執(zhí)行時(shí)被用到。為了讓庫(kù)被別人調(diào)用,我們可以寫一個(gè)頭文件.h,包含函數(shù)原型及聲明。

C語(yǔ)言中什么是庫(kù)函數(shù)?

庫(kù)函數(shù)(Library function)是把函數(shù)放到庫(kù)里,供別人使用的一種方式。.方法是把一些常用到的函數(shù)編完放到一個(gè)文件里,供不同的人進(jìn)行調(diào)用。調(diào)用的時(shí)候把它所在的文件名用#include加到里面就可以了。一般是放到lib文件里的。

一般是指編譯器提供的可在c源程序中調(diào)用的函數(shù)??煞譃閮深?,一類是c語(yǔ)言標(biāo)準(zhǔn)規(guī)定的庫(kù)函數(shù),一類是編譯器特定的庫(kù)函數(shù)。

由于版權(quán)原因,庫(kù)函數(shù)的源代碼一般是不可見(jiàn)的,但在頭文件中你可以看到它對(duì)外的接口

庫(kù)函數(shù)簡(jiǎn)介。

C語(yǔ)言的語(yǔ)句十分簡(jiǎn)單,如果要使用C語(yǔ)言的語(yǔ)句直接計(jì)算sin或cos函數(shù),就需要編寫頗為復(fù)雜的程序。因?yàn)镃語(yǔ)言的語(yǔ)句中沒(méi)有提供直接計(jì)算sin或cos函數(shù)的語(yǔ)句。又如為了顯示一段文字,我們?cè)贑語(yǔ)言中也找不到顯示語(yǔ)句,只能使用庫(kù)函數(shù)printf。

C語(yǔ)言的庫(kù)函數(shù)并不是C語(yǔ)言本身的一部分,它是由編譯程序根據(jù)一般用戶的需要編制并提供用戶使用的一組程序。C的庫(kù)函數(shù)極大地方便了用戶,同時(shí)也補(bǔ)充了C語(yǔ)言本身的不足。事實(shí)上,在編寫C語(yǔ)言程序時(shí),應(yīng)當(dāng)盡可能多地使用庫(kù)函數(shù),這樣既可以提高程序的運(yùn)行效率,又可以提高編程的質(zhì)量。

這里調(diào)用的是靜態(tài)庫(kù)。

函數(shù)庫(kù):函數(shù)庫(kù)是由系統(tǒng)建立的具有一定功能的函數(shù)的集合。庫(kù)中存放函數(shù)的名稱和對(duì)應(yīng)的目標(biāo)代碼,以及連接過(guò)程中所需的重定位信息。用戶也可以根據(jù)自己的需要建立自己的用戶函數(shù)庫(kù)。

庫(kù)函數(shù):存放在函數(shù)庫(kù)中的函數(shù)。庫(kù)函數(shù)具有明確的功能、入口調(diào)用參數(shù)和返回值。

連接程序:將編譯程序生成的目標(biāo)文件連接在一起生成一個(gè)可執(zhí)行文件。

頭文件:有時(shí)也稱為包含文件。C語(yǔ)言庫(kù)函數(shù)與用戶程序之間進(jìn)行信息通信時(shí)要使用的數(shù)據(jù)和變量,在使用某一庫(kù)函數(shù)時(shí),都要在程序中嵌入(用#include)該函數(shù)對(duì)應(yīng)的頭文件。

由于C語(yǔ)言編譯系統(tǒng)應(yīng)提供的函數(shù)庫(kù)尚無(wú)國(guó)際標(biāo)準(zhǔn)。不同版本的C語(yǔ)言具有不同的庫(kù)函數(shù),用戶使用時(shí)應(yīng)查閱有關(guān)版本的C的庫(kù)函數(shù)參考手冊(cè)。我們以Turbo C為例簡(jiǎn)介一下C的庫(kù)函數(shù),并附錄中給出了Turbo C的部分常用庫(kù)函數(shù)。


網(wǎng)頁(yè)名稱:c語(yǔ)言指定靜態(tài)庫(kù)的函數(shù) c語(yǔ)言靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的建立
標(biāo)題網(wǎng)址:http://weahome.cn/article/docjipp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部