先簡單講一下DLL

在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),可以看作同一個東西的不同稱呼。


VC6導出DLL示例

ps:糾結了一下還是用VC6吧,因為它在中國的用戶群體較大,很多人入門C都是從這開始的。這是我第一次在專欄里提到VC6,應該也是最後一次了,它該被淘汰了。後面有gcc的示例。

1.打開Visual C++ 6.0,先創建一個DLL項目,如圖所示:

注意紅框標出的地方,下同

2.新建一個源代碼文件DLL_demo.c,並添加到Source Files里。用實現一個簡單計算的功能作為例子,寫好代碼後,點擊Build,如圖所示:

源碼在最後

3.這時,DLL_demoDebug裡面應該就有這兩個文件了:

函數主體在.dll文件里,函數介面在.lib(library,庫)文件里

4.關閉Workspace,到這步,DLL就算是創建好了,接下來我們試驗一下能不能用。

5.創建一個Win32控制台項目,如圖所示:

6.將之前那兩個文件複製到C_demo文件夾里,如圖所示:

7.新建一個源代碼文件C_demo.c,並添加到Source Files里。寫好代碼後,點擊Build,如圖所示:

源碼在最後

8.這時,C_demoDebug裡面就有了我們要的可執行程序:

9.運行,發現錯誤提示:

我們再把.dll移到.exe同目錄下,再次運行就成功了:


GCC導出DLL示例

補個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~");

return 0;
}

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;
}

以上。


推薦閱讀:
相关文章