導航:首頁 > 源碼編譯 > cc編譯時鏈接動態庫

cc編譯時鏈接動態庫

發布時間:2023-08-25 11:28:21

Ⅰ c++動態鏈接的聲明和實現函數 怎麼做成動態鏈接庫

動態鏈接庫的使用方法,動態鏈接庫的動態調用(也叫顯式調用)可以運用了,但是靜態調用(也叫隱式調用)這種很少見。

(一)先回顧一下,動態鏈接庫和靜態鏈接庫
靜態鏈接庫:lib中的函數不僅被連接,全部實現都被直接包含在最終生成的EXE文件中,只是實現是不可見的。
動態鏈接庫:dll不必被包含在最終的EXE中,靜態調用時僅把函數名或者變數名或者類名鏈接到EXE文件中,而這些東西的實體都只有在運行時才從動態庫中導入到可執行文件中,動態調用的時候EXE文件執行時可以直接動態地引用和卸載DLL文件。
同時,靜態鏈接庫中不能再包含其他的動態鏈接庫或靜態庫,而動態鏈接庫中可以包含其他的動態或靜態庫。

(二)回顧一下VC++支持的DLL:
DLL的編制與具體的編程語言及編譯器無關,動態鏈接庫隨處可見,VC++支持三種DLL:非MFC動態庫、MFC規則DLL和MFC擴展DLL。DLL導出函數(或變數、類)可供應用程序調用;DLL內部函數只能在DLL程序內使用,應用程序無法調用它們。

(三)導出函數的聲明方式:
一種在函數聲明類型和函數名之間加上「_declspec(dllexport)」。
另外一種採用模塊定義(.def)文件聲明,需要在庫工程中添加模塊文件,格式如下:
LIBRARY 庫工程名稱
EXPORTS 導出函數名

(四)DLL的調用方式:
靜態調用中,由編譯系統完成對DLL的載入和應用程序結束時DLL的卸載。
動態調用中,由編程者用API函數載入和卸載DLL(DLL載入—DLL函數地址獲取—DLL釋放)方式。

接下來寫個例子把上面提到的理論都實踐一遍。

一、 函數----創建動態鏈接庫(MFC規則DLL)
1. New--projects--MFC AppWizard(dll)--Regular DLL using shared MFC DLL //取名為MFC_dll
2. def文件中添加:函數名(Add_new)
3. h文件中添加:外部函數聲明//求和函數,函數名為Add_new
extern "C" __declspec(dllexport) int __stdcall Add_new(int a,int b);
4. cpp文件中添加: 外部函數實現
extern "C" __declspec(dllexport) int __stdcall Add_new(int a,int b)
{
return a+b;
}
5. build--set active configuration--win32 release--ok
6. 生成
7. 根目錄下release文件夾中dll,lib與根目錄下h文件即為所需

二、 函數----調用動態鏈接庫(把MFC_dll.dll和MFC_dll.lib拷到工程所在目錄)
//靜態調用(.h可以寫到.cpp文件中)
1. new--projects--win32 console application--an empty project
2. 添加h文件:(test.h)
#pragma comment(lib,"MFC_dll.lib") //告訴編譯器DLL相對應的lib文件所在路徑和文件名
extern "C" _declspec(dllimport) int _stdcall Add_new(int a,int b);//聲明導入函數
3. 添加cpp文件:(main.cpp)
#include "test.h"
int main()
{
cout<<Add_new(10,3);
return 0;
}
//動態調用
#include <stdio.h>
#include <windows.h>
typedef int (* lpAddFun)(int ,int);//定義一個與Add_new函數接受參數類型和返回值均相同的函數指針類型
int main()
{
HINSTANCE hDll;//句柄
lpAddFun addFun;//函數指針
hDll=LoadLibrary("dllTest.dll");//動態載入DLL模塊句柄
if(hDll)
{
addFun=(lpAddFun) GetProcAddress(hDll,"Add_new");//得到所載入DLL模塊中函數的地址
if(addFun)
{
int result=addFun(2,3);
printf("%d",result); } FreeLibrary(hDll);//釋放已經載入的DLL模塊
}
return 0;
}

三、 變數----創建動態鏈接庫(非MFC DLL)
1. new---projects---win32 dynamic-link library----an empty project(Sample)
2. 添加sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
extern int dllGlobalVar;
#endif
3. 添加 sample.cpp
#include "sample.h"
#include <windows.h>
int dllGlobalVar;
bool APIENTRY DllMain(HANDLE hMole,DWORD ul_reason_for_call,LPVOID lpReserved)
//windows在載入DLL時,需要一個入口函數,就如同控制台或DOS程序需要main函數、win32程序需要winmain函數一樣。所以引入一個不做任何操作的預設DllMain的函數版本。是DLL的內部函數。


有一點要注意,如果看到此類宏定義
#ifdef KSCANBAR_EXPORTS
#define KSCANBAR_API __declspec(dllexport)
#else
#define KSCANBAR_API __declspec(dllimport)
#endif
是因為這樣定義一般出現在含有多個項目的解決方案中,這樣可以使從 DLL 導出更簡單的宏的標准方法。此 DLL 中的所有文件都是用命令行上定義的 KSCANBAR_EXPORTS符號編譯的。在使用此 DLL 的任何其他項目上不應定義此符號。這樣,源文件中包含此文件的任何其他項目都會將KSCANBAR_API 函數視為是從 DLL 導入的,而此 DLL 則將用此宏定義的符號視為是被導出的。

Ⅱ C++中動態庫調用動態庫如何調用啊

動態連接庫的創建步驟:
一、創建Non-MFC DLL動態鏈接庫
1、打開File —> New —> Project選項,選擇Win32 Dynamic-Link Library —>sample project—>工程名:DllDemo
2、新建一個.h文件DllDemo.h
以下是引用片段:
#ifdefDllDemo_EXPORTS
#defineDllAPI__declspec(dllexport)
#else
#defineDllAPI__declspec(dllimport)
extern"C"//原樣編譯
{
DllAPIint__stdcallMax(inta,intb);//__stdcall使非C/C++語言內能夠調用API
}
#endif
3、在DllDemo.cpp文件中導入DllDemo.h文件,並實現Max(int,int)函數,以下是引用片段:
#include"DllDemo.h"
DllAPIint__stdcallMax(inta,intb)
{
if(a==b)
returnNULL;
elseif(a>b)
returna;
else
returnb;
}
4、編譯程序生成動態連接庫
二、用.def文件創建動態連接庫DllDemo.dll。
1、刪除DllDemo工程中的DllDemo.h文件。
2、在DllDemo.cpp文件頭,刪除 #include DllDemo.h語句。
3、向該工程中加入一個文本文件,命名為DllDemo.def並寫入如下語句:
LIBRARY MyDll
EXPORTS
Max@1
4、編譯程序生成動態連接庫。
動態鏈接的調用步驟:
一、隱式調用
1、 建立DllCnslTest工程
2、 將文件DllDemo.dll、DllDemo.lib拷貝到DllCnslTest工程所在的目錄
3、 在DllCnslTest.h中添加如下語句:
以下是引用片段:
#defineDllAPI__declspec(dllimport)
#pragmacomment(lib,"DllDemo.lib")//在編輯器link時,鏈接到DllDemo.lib文件
extern"C"
{
DllAPIint__stdcallMax(inta,intb);
}
4、在DllCnslTest.cpp文件中添加如下語句,以下是引用片段:
#include"DllCnslTest.h"//或者#include"DllDemo.h"
voidmain()
{
intvalue;
value=Max(2,9);
printf("TheMaxvalueis%d
",value);
}
5、編譯並生成應用程序DllCnslTest.exe
二、顯式調用
1、 建立DllWinTest工程
2、 將文件DllDemo.dll拷貝到DllWinTest工程所在的目錄或Windows系統目錄下。
3、 用vc/bin下的Dumpbin.exe的小程序,查看DLL文件(DllDemo.dll)中的函數結構。
4、 使用類型定義關鍵字typedef,定義指向和DLL中相同的函數原型指針。
例:
以下是引用片段:
typedefint(*lpMax)(inta,intb);//此語句可以放在.h文件中
5、 通過LoadLibray()將DLL載入到當前的應用程序中並返回當前DLL文件的句柄。
例:
以下是引用片段:
HINSTANCEhDll;//聲明一個Dll實例文件句柄
hDll=LoadLibrary("DllDemo.dll");//導入DllDemo.dll動態連接庫
6、 通過GetProcAddress()函數獲取導入到應用程序中的函數指針。
例:
以下是引用片段:
lpMaxMax;
Max=(lpMax)GetProcAddress(hDLL,"Max");
intvalue;
value=Max(2,9);
printf("TheMaxvalueis%d",value);
7、 函數調用完畢後,使用FreeLibrary()卸載DLL文件。
FreeLibrary(hDll);
8、 編譯並生成應用程序DllWinTest.exe

Ⅲ unix 下的C++編程在編譯時怎麼鏈接動態庫第二個問題 在程序中怎麼調用

你說的是手動顯示調用,不是靜態隱式調用。

#include<dlfcn.h>
此頭文件在編譯時需要加入 -ldl選項
動態鏈接庫 必須加入:-fpic選項。

------
void *dll=NULL;//保存動態鏈接庫的句柄。
int (*dll_fun)(char*)=NULL;//想要調用的函數指針。
dll=dlopen("/lib/XXX.so", RTLD_NOW)//打開so文件。
dll_fun=dlsym(dll,"my_print");//獲取指定函數的指針。
dll_fun("Call my_print");
dlclose(dll)
---
編譯鏈接有兩種方法,
1. 使用-lXX 選項,gcc會自動在庫路徑中鏈接libXX.so的文件 gcc main.c -lstdc++ -omain
2. 在命令行中將庫路徑作為參數傳入。 gcc main.c /lib/libstdc++.so -omain

Ⅳ 如何用c語言調用c++做成的動態鏈接庫

因為c++的各種復雜機制,生成的動態鏈接庫中的符號名是不符合C的機制的,直接鏈接會失敗,一般解決c和c++的鏈接問題是在c++的代碼上進行處理的,只要將你的cpp文件中的函數定義都加上extern "c"前綴,就可以編譯成C可鏈接的庫。如果你只有cpp的庫文件,沒有源碼文件的話,沒法處理。


//a.cpp
extern"C"intcpp_func(){return0;}

//b.c
#include<stdio.h>
intcpp_func();

intmain(){
printf("%d ",cpp_func());
return0;
}

//***compileandlink***
//g++a.cpp-oa.o
//gccb.c-ob.o
//g++a.ob.o-oa.out&&./a.out

Ⅳ C++能不能把類寫成動態鏈接庫

可以,dll只是一種文件類型而已,只不過不能獨自運行,裡面寫什麼東西都行,不明白你為什麼會有這樣的疑問。
實例化的話如果庫已經載入了,載入就是項目屬性裡面把庫填進去就行了(如果是vs環境)。直接引用一下庫的頭文件然後創建對象就可以了。這根本不算個問題啊,你是不是想問動態庫的運行原理呢。

Ⅵ 如何編譯C/Fortran動態/靜態鏈接庫

首先,傳統的編譯,也就是
靜態編譯
是把
源文件
翻譯成目標文件,這個是一次性過程,也就是你所謂的靜態編譯。
後來的Java和.NET等語言,首先編譯成中間形式,然後運行過程中根據需要編譯成本地代碼(注意這個過程不是一次性的,下次運行重新編譯),這個就是JIT(即時編譯)技術,從即時編譯發展出了動態編譯技術
————————————
(傳統的)編譯完成後,像C/C++、Fortran、匯編等語言,可以把多個目標文件合並到一個
庫文件
中,這個就是靜態庫。比如常說的
庫函數
printf就是libc裡面的函數。
如果有了啟動函數(main),main裡面使用了printf,就可以通過
靜態鏈接
技術,從libc中提取出printf所在的文件加入到可執行文件中,如果printf還需要其它函數,就繼續搜索並加入列表,直到形成一個
閉包
。這個就是靜態鏈接。
可是靜態鏈接有個明顯的缺點,如果每個程序都需要printf,那麼printf這個函數的代碼就會同時存在在每個程序中,這樣也太佔地方了吧。所以發明了動態連接技術,其實有兩種形式。無論哪一種,都是首先記錄下需要調用printf這個函數以及所在的
動態庫
,等到運行的時候再載入動態庫,從動態庫中找到真正的printf去執行。
由於,
動態鏈接
技術需要一些額外的信息,傳統的靜態庫是不具備的,這些額外信息主要是重復載入和卸載時所需要的一些代碼,因此需要
動態鏈接庫

閱讀全文

與cc編譯時鏈接動態庫相關的資料

熱點內容
網路流理論演算法與應用 瀏覽:795
java和matlab 瀏覽:388
釘釘蘋果怎麼下app軟體 瀏覽:832
php網站驗證碼不顯示 瀏覽:859
鋁膜構造柱要設置加密區嗎 瀏覽:344
考駕照怎麼找伺服器 瀏覽:884
阿里雲伺服器如何更換地區 瀏覽:972
手機app調音器怎麼調古箏 瀏覽:503
銳起無盤系統在伺服器上需要設置什麼嗎 瀏覽:19
紅旗計程車app怎麼應聘 瀏覽:978
如何編寫linux程序 瀏覽:870
吉利車解壓 瀏覽:248
java輸入流字元串 瀏覽:341
安卓軟體沒網怎麼回事 瀏覽:785
dvd壓縮碟怎麼導出電腦 瀏覽:274
冒險島什麼伺服器好玩 瀏覽:541
如何在伺服器上做性能測試 瀏覽:793
命令序列錯 瀏覽:259
javaif的條件表達式 瀏覽:576
手機app上傳的照片怎麼找 瀏覽:531