欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

全方位解读DLL文件—编写DLL

程序员文章站 2022-03-04 19:04:10
...

前情提要

dll 的编写特别要注意你的编译器选择,我目前也只用了两个主流的编译器做过测试,一个是微软 VisualStudio 自带的 MSVC编译器,另一个是 GNU 在 Windows 上的 MinGW编译器
如果你使用 MinGW,那么和写普通程序区别不大;但如果你使用 MSVC 的话,你就需要注意一些固定的格式,以及一些宏定义

MSVC版

直接新建一个 dll 文件项目,先写一个头文件,把一些变量和函数的定义写好,这里有兴趣的话可以了解一下 #ifdef 以及 extern "C" __declspec(dllimport),头文件 header.h 代码如下

#ifdef MYLIBAPI
#define MYLIBAPI extern "C" __declspec(dllexport)
#else
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
MYLIBAPI int res;
MYLIBAPI int myadd(int num1,int num2);

然后是主要的功能代码,mydll.c 代码如下

#include <windows.h>
#define MYLIBAPI extern "C" __declspec(dllimport)
#include "header.h"
int res;

int myadd(int num1,int num2){
    res = num1 + num2;
    return res;
}

注意事项:
extern "C" 主要是排除 C++ 编译的干扰,C++ 编译某个函数后会变成 [email protected] 的形式,不方便主程序根据函数名调用
__declspec(dllimport) 从其它动态库中声明导入函数、类、对象等供本动态库或exe文件使用,在没有全局静态变量时可以不使用该关键字
__declspec(dllexport) 声明为导出函数、类、对象等供其它程序调用,如果不使用该关键字导出 dll 函数,则需要 .def 文件

MinGW版

使用 MinGW 编译器的话和写普通程序类似,只写需要用到的函数即可,不需要 main 主函数,然后编译成 dll 文件即可。编译一句搞定 gcc math.c -shared -o math.dll -Wl,--out-implib,math.lib,--output-def,math.def,还能生成 .lib 以及 .def 文件,用 C++ 的话可能还需要 --kill-at,mydll.c 代码如下:

#include<stdio.h>
int add(int a,int b){
    return a+b;
}
int sub(int a,int b){
    return a-b;
}
int mul(int a,int b){
    return a*b;
}
int div(int a,int b){
    return a/b;
}
// gcc math.c -shared -o math.dll -Wl,--out-implib,math.lib,--output-def,math.def

注意: dll 程序其实也是有入口函数的-DllMain,操作系统在调用 LoadLibrary() 线程的上下文中调用此入口函数,并且入口函数中通常会说明该 dll 被调用的方式!除非有特殊需求,一般不需要写 DllMain 函数

END