在Windows下,DLL(DLL,Dynamic Link Library,動態鏈接庫)是一個被編譯過的二進位程序,但與.exe文件不同,.dll文件不能獨立運行,必須由其他程序調用。
為什麼有這東西呢?當然有其存在的好處啦:
1.不限語言
我們可以用自己熟悉的語言寫DLL,然後由其他語言寫的可執行程序來調用這些DLL。例如,可以用Python寫程序的主界面,然後調用C寫的實現一個具體功能的DLL模塊。
2.增強功能
我們看到許多產品都提供了界面插件功能,允許用戶動態地更換程序的界面,這就可以通過更換界面DLL來實現。
3.簡化管理
在一個大型項目開發中,通常都是由多個項目小組同時開發。我們可以將項目細分,將不同功能交由各項目小組以多個DLL的方式實現,這樣,各個項目小組就可以同時進行開發了。
4.節省空間
如果多個應用程序需要同樣的功能,那麼可以將該功能以DLL的形式提供,這樣在機器上只需要存在一份該DLL文件就可以了。另外,如果多個應用程序使用同一個DLL,該DLL只需要放入內存一次,所有的應用程序就都可以共享它了。
在Linux環境下沒有.dll文件,但也有類似的,對應的文件後綴名一般是.so(Share Object),可以看作同一個東西的不同稱呼。
ps:糾結了一下還是用VC6吧,因為它在中國的用戶群體較大,很多人入門C都是從這開始的。這是我第一次在專欄里提到VC6,應該也是最後一次了,它該被淘汰了。後面有gcc的示例。
1.打開Visual C++ 6.0,先創建一個DLL項目,如圖所示:
2.新建一個源代碼文件DLL_demo.c,並添加到Source Files里。用實現一個簡單計算的功能作為例子,寫好代碼後,點擊Build,如圖所示:
3.這時,DLL_demoDebug裡面應該就有這兩個文件了:
4.關閉Workspace,到這步,DLL就算是創建好了,接下來我們試驗一下能不能用。
5.創建一個Win32控制台項目,如圖所示:
6.將之前那兩個文件複製到C_demo文件夾里,如圖所示:
7.新建一個源代碼文件C_demo.c,並添加到Source Files里。寫好代碼後,點擊Build,如圖所示:
8.這時,C_demoDebug裡面就有了我們要的可執行程序:
9.運行,發現錯誤提示:
我們再把.dll移到.exe同目錄下,再次運行就成功了:
補個GCC的 @Zombie110year
gcc -shared -o dll.dll dll.c
gcc -o main.exe main.c dll.dll
C_demo.c
#include <stdio.h> #pragma comment(lib, "DLL_demo.lib") extern double add(double, double); extern double sub(double, double); extern double mul(double, double); extern double div(double, double);
int main(void) { double a, b; char op, c; puts("Please input a formula and get the result. (enter q to quit) "); while (1) { printf("Enter: "); if (scanf("%lf %c %lf", &a, &op, &b) == 3) switch (op) { case +: printf("%.2lf + %.2lf = %.2lf ", a, b, add(a, b)); break; case -: printf("%.2lf - %.2lf = %.2lf ", a, b, sub(a, b)); break; case *: printf("%.2lf * %.2lf = %.2lf ", a, b, mul(a, b)); break; case /: printf("%.2lf / %.2lf = %.2lf ", a, b, div(a, b)); break; default : printf("Enter error! "); } else { if ((c = getchar()) == q) break; puts("Enter error!"); while (getchar() != ) continue; } } puts("Bye~"); getchar(); getchar();
return 0; }
DLL_demo.c
_declspec(dllexport) double add(double a, double b) { return a + b; }
_declspec(dllexport) double sub(double a, double b) { return a - b; }
_declspec(dllexport) double mul(double a, double b) { return a * b; }
_declspec(dllexport) double div(double a, double b) { return a / b; }
main.c
#include <stdio.h> extern double add(double, double); extern double sub(double, double); extern double mul(double, double); extern double divi(double, double); //div會和庫函數名衝突 int main(void) { double a, b; char op, c; puts("Please input a formula and get the result. (enter q to quit) "); while (1) { printf("Enter: "); if (scanf("%lf %c %lf", &a, &op, &b) == 3) switch (op) { case +: printf("%.2lf + %.2lf = %.2lf ", a, b, add(a, b)); break; case -: printf("%.2lf - %.2lf = %.2lf ", a, b, sub(a, b)); break; case *: printf("%.2lf * %.2lf = %.2lf ", a, b, mul(a, b)); break; case /: printf("%.2lf / %.2lf = %.2lf ", a, b, divi(a, b)); break; default : printf("Enter error! "); } else { if ((c = getchar()) == q) break; puts("Enter error!"); while (getchar() != ) continue; } } puts("Bye~");
dll.c
double add(double a, double b) { return a + b; }
double sub(double a, double b) { return a - b; }
double mul(double a, double b) { return a * b; }
double divi(double a, double b) { return a / b; }
以上。