testdll.h:
#ifndef TESTDLL_H
#define TESTDLL_H
#ifdef DLL_EXPORT
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
DLLAPI float funadd(float a, float b);
#ifdef __cplusplus
}
#endif
#endif
testmain.c:#include
#include "testdll.h"
int main(void)
{
float a,b,c;
a=1.0;
b=2.0;
c=funadd(a,b);
printf("%f \n",c);
getchar();
}
testdll.c:
#include "testdll.h"
float funadd(float a, float b)
{
return (a+b);
}
gcc -c -DDLL_EXPORT (-fPIC) testdll.cPS : 會產生testdll.o的檔案...還有x86平台,-fPIC會忽略
gcc -shared -o testdll.dll testdll.o -Wl,--output-def,testdll.def,--out-implib,testdll.libPS : 產生三個檔案:
testdll.dll:也就是程式執行時載入的dll檔
testdll.def:若有需要和VC編譯器連結,這個檔會需要
testdll.lib:export library,用來連結主程式,這樣主程式才能知道找哪個dll,那個dll裡有哪些函式跟參數....
gcc -c testmain.cPS : 用來使用dll的主程式,會產生一個testmain.o的檔案
gcc -static -o test.exe testmain.o -L. -ltestdllPS : 會讓主程式和export library(testdll.lib)靜態連結起來,產生test.exe的可執行檔
由於dll和主程式都是用MinGW產生的,所以可以簡化上面的步驟,不過上面的解說,可以對執行檔組成了解多一些,以下舉兩個例子
方法一:
gcc -shared -o testdll.dll testdll.c
PS : -shared是linker的參數,這裡直接產生testdll.dll
gcc -c testmain.c
PS : -c:只編譯不連結,產生testmain.o
gcc -o test.exe testmain.o testdll.dll
PS : 我也不知給什麼規則,反正MinGW搞得定這個testdll.dll就對了
方法二:
gcc -shared -o testdll.dll testdll.c
gcc -o test.exe testmain.c -L. -ltestdll
PS : -l:unix環境裡,會找libtestdll.a(-static) 或 libtestdll.so(-shared),在函式庫名稱的命名上,前面一定要有lib
不過MinGW對於這個慣例,放寬許多,來讓熟悉windows的人習慣
for (-static) : 會找libtestdll.a 或 testdll.lib
for (-shared) : 會找libtestdll.so . testdll.dll 或 libtestdll.dll
希望看完之後是感覺"條條道路通羅馬",而不是給它一整個亂...
這裡又牽扯出另一個疑問,那就是MinGW的make,它對於字尾規則和函式庫的處理,是否有加上這些擴充,有空在研究好了
PS:MinGW的官方網站,有提供一個Shell,叫MSYS,之前發現MinGW和MSYS都有自己的make,MinGW的make叫mingw32-make.exe,MSYS的make叫make.exe,其中MSYS的make是unix style,不能分辨'\',組成的路徑字串(windows是用'\',組成路徑字串),也許這兩個make除了這個區別,還包括了字尾規則和函式庫處理的差異...
testdll.h的補充說明:
關於DLL_EXPORT 的定義,應該要在編譯testdll.c時定義,來分別dllimport和dllexport,不過我沒加,也沒錯誤,我不知道MinGW有沒有支援__declspec(dllimport)和__declspec(dllexport) 這些關鍵字...
關於extern "C" {},如果使用gcc,且souce code的附檔名是.c,會有錯誤,不過__cplusplus沒有定義,會避開...
如果附檔名是.cpp,或gcc改g++,則__cplusplus會定義,就會使函數的Name Mangling使用C的形式(簡單的那一種),常看到...
這裡的紀錄,主要都是看了別人的文章,試出來的...我盡量有系統性,不過最好還是參考相關主要說明文件
沒有留言:
張貼留言