A. 我在一個機器上編了個動態庫,在另一個機器上編譯了一個引用這個動態庫的可執行程序,能調用不
什麼語言?C++還是C#?Native還是managed?
一般是沒有問題的,只要保證:
1、你這個動態庫沒有依賴其他動態庫(包括系統的、MFC的、CRT的、VC的、或者.NET Framework的),或者依賴的其他動態庫在另一台機器上也都有;
2、而且不存在32位和64位的兼容問題(即動態庫以及可執行程序都是32位的或者都是64位的,而且操作系統也不存在這個兼容性的差異);
3、可執行程序連接動態庫使用的LIB文件和動態庫是匹配的(如果是native的)
____________________
補充:
哦~~~ linux我是門外漢了,那就看看其他朋友有沒有Linux大拿幫忙回答一下吧……
B. VC程序調用動態庫,編譯時候也跟著編譯動態庫
不太清楚你的工程是如何建立的,想必一個工程是生成動態鏈接庫,另一個是調用程序EXE了。由於VC動態庫有兩種形式,Regular和Extended兩種,其中一種能導出類,另一種只能導出變數和函數。如果導出的是類,你在編譯EXE文件時自然需要用到類得聲明文件,即你前面所說的動態庫本身所引用的文件。如果導出的是函數或變數,有可能出現的情況是:一般為了代碼的重用性,把需要導出的函數或變數單獨放在一個頭文件中,用一個宏控制其導入、導出。編譯動態庫時,宏定義為導出,編譯EXE時,宏變為導入,這個頭文件為兩者共用。如果不小心在這個頭文件中包含了其他頭文件,也可能出現你說的情況。如果動態庫調用直接採用函數入口地址的方法,則什麼都不用聲明,當然,只適用於導出函數與變數的情形。
C. 怎樣使用動態庫中的條件編譯
publicstaticvoidabc(){#region要執行的代碼stringstrCode=@"usingSystem;usingSystem.Text;usingSystem.Collections.Generic;usingSystem.Linq;namespaceaaa{publicclassbbb{publicstaticstringccc(stringname){return""abc"";}}}";#endregion#region編譯參數=newCompilerParameters();objCompilerParams.GenerateExecutable=false;//編譯成exe還是dllobjCompilerParams.GenerateInMemory=false;//是否寫入內存,不寫入內存就寫入磁碟objCompilerParams.OutputAssembly="E:\abc.dll";//輸出路徑objCompilerParams.IncludeDebugInformation=false;//是否產生pdb調試文件默認是falseobjCompilerParams.ReferencedAssemblies.Add("System.dll");objCompilerParams.ReferencedAssemblies.Add("System.Core.dll");//編譯器選項:編譯成(存儲在內存中)的DLL/*objCompilerParams.CompilerOptions="/target:library/optimize";//編譯時在內存輸出objCompilerParams.GenerateInMemory=true;//不生成調試信息objCompilerParams.IncludeDebugInformation=false;*/#endregion#region編譯//創建編譯類CSharpCodeProviderobjCompiler=newCSharpCodeProvider();//進行編譯=objCompiler.CompileAssemblyFromSource(objCompilerParams,strCode);#endregion#region取得編譯成程序集,准備執行程序集里的類中的方法//獲取編譯結果:程序集AssemblyobjAssembly=objCompileResults.CompiledAssembly;//獲取編譯成的程序集的信息/*objectobjMainClassInstance=objAssembly.CreateInstance("Program");TypeobjMainClassType=objMainClassInstance.GetType();*/#endregion#region調用程序集中的類,執行類中的方法,得到結果/*objMainClassType.GetMethod("Main").Invoke(objMainClassInstance,null);objMainClassType.GetMethod("PrintWorld").Invoke(objMainClassInstance,null);*/#endregion
D. 動態庫鏈接編譯
這里的動態的意思應該是模塊代碼是動態載入的
而不是隨著應用程序一起編譯
只要動態庫里的函數介面不變
應用程序就無需重新編譯
只需將動態庫重新編譯後替換掉舊的動態庫即可
如果動態庫的函數介面有變動
那麼應用程序就要重新編譯發布
這也是我的個人理解~~~
E. 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
F. 如何讓自己的程序動態引用debug和release的庫
本文所描述的動態庫是基於MFC的。IDE是VS2005. 默認情況下,如果一個動態庫工程名叫A,動態庫的名稱將是A.lib A.dll A.def。不管工程是release下還是debug下。這就導致一個問題。如果我在另一個工程中使用這個動態庫,這個工程在release下應該鏈接release下的相應庫文件,這個工程在debug下應該鏈接debug下的相應庫文件。於是乎,可能需要來回拷貝覆蓋。甚是麻煩。為什麼我們的動態庫工程不能像OpenCV那樣,debug就將默認生成的庫名由默認的A.lib A.dll換成Ad.lib和Ad.dll呢?如果這能實現,我們在使用這些庫的工程中的"項目"->"屬性"->"鏈接器"->"輸入"->"附加依賴庫"裡面分別設置不就OK了嗎。 修改動態庫名稱的方法如下:(1) 打開動態庫工程,設置DEBUG模式,然後選擇"項目"->"屬性"->"鏈接器"->"常規"->"輸出文件",一般在文件名後附加 'd'即可。(2) 選擇"項目"->"屬性"->"鏈接器"->"高級"->"導入庫",一般在文件名後附加 'd'即可。(3) 選擇"項目"->"屬性"->"鏈接器"->"輸入"->"模塊定義文件",一般在文件名後附加 'd'即可。注意:這里是需要一個模塊定義文件,工程下默認只有 "工程名.def" 文件,需要將該文件復制一份,然後修改其中LIBRARY 後面引號中的內容加一個d。如; ListCtrlEx.def : Declares the mole parameters for the DLL.LIBRARY "ListCtrlEx" DESCRIPTION 'ListCtrlEx Windows Dynamic Link Library'EXPORTS ; Explicit exports can go here 修改後為:; ListCtrlEx.def : Declares the mole parameters for the DLL.LIBRARY "ListCtrlExd" ; Explicit exports can go here 如果不做這一步,在編譯動態庫時會出現如下警告 (4) release的個人認為無需改變。這樣選擇菜單"生成"->"批生成"生成debug和release版本的庫。 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 到這里我們大概完成了任務的80%。接下來就像使用很多開源軟體包一樣,設置我們自己的工程。(1) 選擇"項目"->"選項"->"項目和解決方案"->"C++目錄",選擇庫文件,然後將剛剛生成的debug和release版本的庫的路徑填入。
G. 如何確定程序調用了動態庫或者靜態庫
可以得出第一個結論:都為靜態鏈接庫,有同名函數參與情況下,鏈接會出現符號多次定義的錯誤!
兩個動態庫
再來看看動態鏈接庫,同樣的libA libB 生成動態鏈接庫
測試主程序不修改 ! 還是為:
這種編譯方式叫做動態庫的隱式調用, 如果你刪除一個libA.so , 運行a.out 會出現不能找到動態庫的錯誤.
這種情況也可以稱為 載入時鏈接! 靜態庫屬於編譯時鏈接!
可以得出第二個結論: 若都為動態庫,並且進行隱式調用,輸出結果和動態庫的順序有關.
再繼續看看動態載入動態庫.
修改測試主程序
同樣可以得出結論,動態鏈接庫如果不加庫連選項 ,函數調用是正確的 加庫路徑,會以庫的路徑順序為主! 左邊覆蓋右邊. 而且當只鏈接其中一個時 也生效
H. linux 編譯怎麼連接動態庫
Linux的動態庫文件是以lib字樣開頭的.so文件,編譯鏈接動態庫有兩個要點:一個是需要用-L選項指定動態庫的搜索路徑,這個搜索路徑是需要連接的so文件的大致路徑,比如/usr/openssl/lib;另外還需要用-l(這個是小寫的L)選項指定動態庫的名字,比如下面這條編譯命令:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
I. 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