Ⅰ QT程序怎麼調用vc,編譯的靜態庫,動態庫等
mingw編譯出來的靜態庫後綴名為.a,編譯出來的動態庫的導入庫後綴名為.dll.a,而在windows下後綴名為.lib的庫可能是靜態庫也可能是動態庫的導入庫。 mingw編譯出來的動態庫的導入庫可以直接在vc中直接使用
Ⅱ 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
Ⅲ 請教關於android linux動態庫.so的載入調用
1、 .so動態庫的生成
可使用gcc或者g++編譯器生成動態庫文件(此處以g++編譯器為例)
g++ -shared -fPIC -c XXX.cpp
g++ -shared -fPIC -o XXX.so XXX.o
2、 .so動態庫的動態調用介面函數說明
動態庫的調用關系可以在需要調用動態庫的程序編譯時,通過g++的-L和-l命令來指定。例如:程序test啟動時需要載入目錄/root/src/lib中的libtest_so1.so動態庫,編譯命令可照如下編寫執行:
g++ -g -o test test.cpp –L/root/src/lib –ltest_so1
(此處,我們重點講解動態庫的動態調用的方法,關於靜態的通過g++編譯命令調用的方式不作詳細講解,具體相關內容可上網查詢)
Linux下,提供專門的一組API用於完成打開動態庫,查找符號,處理出錯,關閉動態庫等功能。
下面對這些介面函數逐一介紹(調用這些介面時,需引用頭文件#include <dlfcn.h>):
1) dlopen
函數原型:void *dlopen(const char *libname,int flag);
功能描述:dlopen必須在dlerror,dlsym和dlclose之前調用,表示要將庫裝載到內存,准備使用。如果要裝載的庫依賴於其它庫,必須首先裝載依賴庫。如果dlopen操作失敗,返回NULL值;如果庫已經被裝載過,則dlopen會返回同樣的句柄。
參數中的libname一般是庫的全路徑,這樣dlopen會直接裝載該文件;如果只是指定了庫名稱,在dlopen會按照下面的機制去搜尋:
a.根據環境變數LD_LIBRARY_PATH查找
b.根據/etc/ld.so.cache查找
c.查找依次在/lib和/usr/lib目錄查找。
flag參數表示處理未定義函數的方式,可以使用RTLD_LAZY或RTLD_NOW。RTLD_LAZY表示暫時不去處理未定義函數,先把庫裝載到內存,等用到沒定義的函數再說;RTLD_NOW表示馬上檢查是否存在未定義的函數,若存在,則dlopen以失敗告終。
2) dlerror
函數原型:char *dlerror(void);
功能描述:dlerror可以獲得最近一次dlopen,dlsym或dlclose操作的錯誤信息,返回NULL表示無錯誤。dlerror在返回錯誤信息的同時,也會清除錯誤信息。
3) dlsym
函數原型:void *dlsym(void *handle,const char *symbol);
功能描述:在dlopen之後,庫被裝載到內存。dlsym可以獲得指定函數(symbol)在內存中的位置(指針)。如果找不到指定函數,則dlsym會返回NULL值。但判斷函數是否存在最好的方法是使用dlerror函數,
4) dlclose
函數原型:int dlclose(void *);
功能描述:將已經裝載的庫句柄減一,如果句柄減至零,則該庫會被卸載。如果存在析構函數,則在dlclose之後,析構函數會被調用。
3、 普通函數的調用
此處以源碼實例說明。各源碼文件關系如下:
test_so1.h和test_so1.cpp生成test_so1.so動態庫。
test_so2.h和test_so2.cpp生成test_so2.so動態庫。
test_dl.cpp生成test_dl可執行程序,test_dl通過dlopen系列等API函數,並使用函數指針以到達動態調用不同so庫中test函數的目的。
Ⅳ 動態庫鏈接編譯
這里的動態的意思應該是模塊代碼是動態載入的
而不是隨著應用程序一起編譯
只要動態庫里的函數介面不變
應用程序就無需重新編譯
只需將動態庫重新編譯後替換掉舊的動態庫即可
如果動態庫的函數介面有變動
那麼應用程序就要重新編譯發布
這也是我的個人理解~~~
Ⅳ 怎麼動態調用第三方庫
說些我自己明白的:
動態載入:就是省略了把符號編譯到二進制的步驟,需要用函數的時候直接載入動態庫,然後從動態庫里找指定函數。
靜態編譯與動態編譯的區別
動態編譯的可執行文件需要附帶一個的動態鏈接庫,在執行時,需要調用其對應動態鏈接庫中的命令。所以其優點一方面是縮小了執行文件本身的體積,另一方面是加快了編譯速度,節省了系統資源。缺點一是哪怕是很簡單的程序,只用到了鏈接庫中的一兩條命令,也需要附帶一個相對龐大的鏈接庫;二是如果其他計算機上沒有安裝對應的運行庫,則用動態編譯的可執行文件就不能運行。 靜態編譯就是編譯器在編譯可執行文件的時候,將可執行文件需要調用的對應動態鏈接庫(.so)中的部分提取出來,鏈接到可執行文件中去,使可執行文件在運行的時候不依賴於動態鏈接庫。所以其優缺點與動態編譯的可執行文件正好互補。
Ⅵ 關於動態庫調用的問題
動態調用的時候指針名不需要和原DLL中函數一樣。基本過程是這樣的:
HMUDOLE hmodle=GetMuleHandle("你要使用的DLL名字");
PROC fun=(PROC)GetProcAddress(hmole,"DLL中函數名");
然後將fun轉換成你的函數形式,比如你要調用的DLL中函數是
int myfun(int a,int b){。。。}
你可以這樣轉換:
typedef int (*MYFUN)(int a,int b);
(MYFUN)fun(10,20);//然後這樣調用
函數指針和函數名都是一個指向函數入口地址的指針,函數入口地址是一個4位元組類型的值而已,函數指針指示一個保存這個值的變數而已,名字只要合法就行,不需要和所指向的函數名一樣,而且,編譯後就沒函數名這概念了。
Ⅶ 如何用java調用c++動態庫
Java是通過JNI調用其他語言(包括C++)編譯的本地方法的,而本地方法是以庫文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX機器上是SO文件形式)。
如下是詳細講解:
1、JAVA中所需要做的工作
在JAVA程序中,首先需要在類中聲明所調用的庫名稱,如下:
static {
System.loadLibrary(「goodluck」);
}
在這里,庫的擴展名字可以不用寫出來,究竟是DLL還是SO,由系統自己判斷。
還需要對將要調用的方法做本地聲明,關鍵字為native。並且只需要聲明,而不需要具體實現。如下:
public native static void set(int i);
public native static int get();
然後編譯該JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就會生成C/C++的頭文件。
例如程序TestDll.java,內容為:
public class TestDll
{
static
{
System.loadLibrary("goodluck");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args)
{
TestDll test = new TestDll();
test.set(10);
System.out.println(test.get());
}
}
用javac TestDll.java編譯它,會生成TestDll.class。
再用javah TestDll,則會在當前目錄下生成TestDll.h文件,這個文件需要被C/C++程序調用來生成所需的庫文件。
2、C/C++中所需要做的工作
對於已生成的.h頭文件,C/C++所需要做的,就是把它的各個方法具體的實現。然後編譯連接成庫文件即可。再把庫文件拷貝到JAVA程序的路徑下面,就可以用JAVA調用C/C++所實現的功能了。
接上例子。我們先看一下TestDll.h文件的內容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestDll */
#ifndef _Included_TestDll
#define _Included_TestDll
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_TestDll_get (JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_TestDll_set (JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
在具體實現的時候,我們只關心兩個函數原型
JNIEXPORT jint JNICALL Java_TestDll_get (JNIEnv *, jclass);
和
JNIEXPORT void JNICALL Java_TestDll_set (JNIEnv *, jclass, jint);
這里JNIEXPORT和JNICALL都是JNI的關鍵字,表示此函數是要被JNI調用的。而jint是以JNI為中介使JAVA的int類型與本地的int溝通的一種類型,我們可以視而不見,就當做int使用。函數的名稱是JAVA_再加上java程序的package路徑再加函數名組成的。參數中,我們也只需要關心在JAVA程序中存在的參數,至於JNIEnv*和jclass我們一般沒有必要去碰它。
下面我們用TestDll.cpp文件具體實現這兩個函數:
#include "TestDll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_TestDll_get (JNIEnv *, jclass)
{
return i;
}
JNIEXPORT void JNICALL Java_TestDll_set (JNIEnv *, jclass, jint j)
{
i = j;
}
編譯連接成庫文件,本例是在WINDOWS下做的,生成的是DLL文件。並且名稱要與JAVA中需要調用的一致,這里就是goodluck.dll
把goodluck.dll拷貝到TestDll.class的目錄下,java TestDll運行它,就可以觀察到結果了。
Ⅷ linux c++動態庫 調用 c動態庫函數
先把.cpp編譯成動態庫,編譯方法:
g++ *.cpp –fPIC –shared –o libtest.so -libyourclib.so
其中,*.cpp表示你的.cpp文件,你可以把它們一一列出,
–fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的,所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。
–shared:指明編譯成動態庫。
libtest.so即為生成的動態庫,以lib開頭,方便後面使用
-libyourclib.so 是你的c動態庫名
編譯好之後,就可以來編譯你的測試程序了:
gcc test.c -o test -ltest
其中,test是生成的可執行程序
-ltest表示引用生成的動態庫libtest.so
大概過程就是這樣,你先試一試
Ⅸ VS2010的MFC程序如何調用動態庫文件(dll文件)放在system32中仍然編譯無法打開d
dll這個東西,只要放到編譯時會去訪問的任意路徑上即可。
比如你現在是Debug,你可以放到Debug文件夾或者工程文件夾;
你現在是Release, 你可以放到Release文件夾或者工程文件放到System32無法訪問可能說明你的程序根本不需要去訪問System32,雖然這不太可能。
當然我可以認為樓主是在隱式調用dll, 顯示調用失敗系統不會報錯。如果 你是要隱式調用已經知道庫在何處和其中函數定義的dll,可以在你的FingerMatch.cpp開始的時候寫上:
#ifdef _DEBUG
#pragma comment(lib, "..(路徑)fp.lib")
#else
#pragma comment(lib, "..(路徑)fp.lib")
#endif
然後包含一下fp.h,這個應該是已經做了。那應該不會有什麼問題了。
值得注意的是編譯時dll只會打開一次,比如你在Debug文件夾下有一個fp.dll,在工程文件夾下也有一個fp.dll,那麼編譯時使用的是Debug文件夾下的dll,因為它先被找到。
如果上面說的都沒用,那麼你顯式調用吧
Ⅹ 如何創建與調用動態鏈接庫
動態鏈接庫:dll不必被包含在最終的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釋放)方式。
所有庫工程編譯時必須Release方式:
Build—set active configuration—選擇庫工程的release方式
示例:
一、 函數----創建動態鏈接庫(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的內部函數。