0x01. declspec(dllexport)创建导出dll

笔者这边使用vs 2015,但是性质都一样的



新建项目 -》 Win32控制台应用程序 -》 dll



这时候就创建了一个项目



我们在头文件和源文件创建下文件

头文件 test.h

extern "C" _declspec(dllexport) int Plus(int x, int y);
extern "C" _declspec(dllexport) int Sub(int x, int y);
extern "C" _declspec(dllexport) int Mul(int x, int y);
extern "C" _declspec(dllexport) int Div(int x, int y);

说明:

1、extern 表示这是个全局函数,可以供各个其他的函数调用;

2、"C" 按照C语言的方式进行编译、链接

__declspec(dllexport)告诉编译器此函数为导出函数;

3、也可以在int类型后面加个调用约定,决定外平栈还是内平栈

详细的调用约定和dll之间的关系可以查看这篇文章:https://blog.csdn.net/qq_34696097/article/details/89639184

源文件:main.cpp

#include "test.h"

int Plus(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x*y;
}
int Div(int x, int y)
{
return x / y;
}

0x02. .def创建导出dll

test.h:

int Plus(int x, int y);
int Sub(int x, int y);
int Mul(int x, int y);
int Div(int x, int y);

main.cpp

#include "test.h"

int Plus(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x*y;
}
int Div(int x, int y)
{
return x / y;
}
EXPORTS	

Plus   	@12
Sub @15 NONAME
Mul @13
Div @16

//函数名 12(这是导出序号,是12,可以随便写)

//NONAME 意思是说只有序号,没有名字

//可以通过这种方式隐藏起来

0x03. 方式一:隐式调用DLL

步骤1:将 *.dll *.lib 放到工程目录下面

步骤2:将 #pragma comment(lib,"DLL名.lib") 添加到调用文件中

步骤3:加入函数的声明

extern "C" __declspec(dllimport)  int Plus(int x, int y);
extern "C" __declspec(dllimport) int Sub(int x, int y);
extern "C" __declspec(dllimport) int Mul(int x, int y);
extern "C" __declspec(dllimport) int Div(int x, int y);

注意一些差别,上面的是__declspec(dllexport),而我们使用的时候是用 __declspec(dllimport)

意味着引用,导入的意思,就会调用这个函数了

extern "C" :调用的时候把这一串删掉也没事,但是为了养成好习惯,还是留着吧

0x04. 方式二:显示调用

步骤1://定义函数指针

      typedef int( *lpPlus)(int, int);
typedef int( *lpSub)(int, int);
typedef int( *lpMul)(int, int);
typedef int( *lpDiv)(int, int);

步骤2://声明函数指针变量

      lpPlus myPlus;
lpSub mySub;
lpMul myMul;
lpDiv myDiv;

步骤3://动态加载dll到内存中

HINSTANCE hModule = LoadLibrary(L"DllTest.dll");

步骤4://获取函数地址一

      myPlus = (lpPlus)GetProcAddress(hModule, "Plus");
mySub = (lpSub)GetProcAddress(hModule, "Sub");
myMul = (lpMul)GetProcAddress(hModule, "Mul");
myDiv = (lpDiv)GetProcAddress(hModule, "Div");
  //获取函数地址二(例如之前如果使用了__stdcall的话就是另外一种方式)
      myPlus = (lpPlus)GetProcAddress(hModule, "_Plus@8");
mySub = (lpSub)GetProcAddress(hModule, "_Sub@8");
myMul = (lpMul)GetProcAddress(hModule, "_Mul@8");
myDiv = (lpDiv)GetProcAddress(hModule, "_Div@8");
  函数名前面有个下划线,然后@后面的8,8就是因为有两个int,一个int是4字节,所以会是8

步骤5://调用函数

      int a = myPlus(10, 2);
int b = mySub(10, 2);
int c = myMul(10, 2);
int d = myDiv(10, 2);



源代码:

#include <stdio.h>
#include <windows.h> typedef int( *lpPlus)(int, int);
typedef int( *lpSub)(int, int);
typedef int( *lpMul)(int, int);
typedef int( *lpDiv)(int, int); int main()
{
lpPlus myPlus;
lpSub mySub;
lpMul myMul;
lpDiv myDiv; HINSTANCE hModule = LoadLibrary(L"DllTest.dll"); myPlus = (lpPlus)GetProcAddress(hModule, "Plus");
mySub = (lpSub)GetProcAddress(hModule, "Sub");
myMul = (lpMul)GetProcAddress(hModule, "Mul");
myDiv = (lpDiv)GetProcAddress(hModule, "Div"); int x = myPlus(10, 20);
printf("%d", x); return 0;
}

c语言创建dll以及使用的更多相关文章

  1. C语言创建并使用dll

    利用C语言创建 利用 C++使用: 参见前面  利用C语言创建并使用lib 如法炮制创建 showDll Dll代码 __declspec(dllexport) double myDivision(i ...

  2. Visual Studio 2019 使用C语言创建动态链接库(Dll)并使用C语言和C#实现调用

    参考网址:https://blog.csdn.net/weixin_34976988/article/details/99625533 一.创建DLL1.建立动态链接库项目 2.创建头文件和源文件 删 ...

  3. 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试

    from:http://m.blog.csdn.net/article/details?id=51075023 在VS2015中先创建C#项目,然后再创建要编写的动态库DLL项目,这样做的好处是整个解 ...

  4. VC++2008 用空工程创建 DLL

    VC++2008 用空工程创建 DLL 一.创建 DLL 工程项目: 1)点击菜单[File] -> [New] -> [Project...] 弹出 “New Project” 对话框: ...

  5. 在VS2015中用C++创建DLL并用C++调用且同一时候实现对DLL的调试

    一:用C++创建DLL            依照[在VS2015中用C++编写可被其他语言调用的动态库DLL]提示创建C++编写的DLL.或參考[在VS2015中用C++创建DLL并用C#调用且同一 ...

  6. C#创建dll类库

    类库让我们的代码可复用,我们只需要在类库中声明变量一次,就能在接下来的过程中无数次地使用,而无需在每次使用前都要声明它.这样一来,就节省了我们的内存空间.而想要在类库添加什么类,还需取决于类库要实现哪 ...

  7. 创建dll教程

    先看我的总结: 总结: 1.头文件中如果想以C形式提供,要判断,如果定义了 _cplusplus, extern "c"{  这里写接口声明 } 2.接口声明中,要表明接口接入点的 ...

  8. Java JNI调用c语言的dll测试

    最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下: 环境:windows 10(64位) + JDK(32位,版本1.7.0 ...

  9. windows编程:创建DLL

    创建DLL Dll是动态链接库的缩写,可以作为附加代码动态映射到进程的地址空间中. 动态库的一般创建方法如下 方法1.使用 __declspec(dllexport)  方式导出 一般的框架如下 // ...

随机推荐

  1. RectTransform简析

    UGUI简述   UGUI主要提供了两个能力 UI元素的渲染与适配(其中UI元素的Mesh中的position信息就是通过RectTransform生成的,本文重点) 设备事件的响应与处理(Event ...

  2. EasyUI 日期控件赋值

    $("#BillDateE").datebox("setValue", '2020/9/28'); $("#BillDateB").date ...

  3. SQL Server 子查询遇到的坑

    这两天改 Bug 时使用 Sql Server 的子查询遇到了一些问题,特此记录一下,之前用 MySQL 比较多,按照 MySQL 的语法其实是没有问题的. 以下面这张表为例: 执行以下 SQL: s ...

  4. Go 数组&切片

    数组相关 在Go语言中,数组是一种容器相关的数据类型,用于存放多种相同类型的数据. 数组定义 在定义数组时,必须定义数组的类型以及长度,数组一经定义不可进行改变. 同时,数组的长度是按照元素个数进行统 ...

  5. Python numpy总结(3)——常用函数用法

    1,np.ceil(x, y) 限制元素范围,进一法,即向上取整. x 表示输入的数据  y float类型 表示每个元素的上限. a = np.array([-1.7, -1.5, -0.2, 0. ...

  6. safari 浏览器版本升级后提示“此网页出现问题,已重新载入网页” 解决办法

    safari回退条件 版本回退的前提是关闭电脑的SIP机制,命令行 csrutil status 检测状态.Mac os 10.14以下版本回退Safari后插件还是可以用的,升了新系统退了也没法用了 ...

  7. MySQL的8小时连接超时时间,导致系统过夜即崩溃,报错Could not roll back Hibernate transaction

    2014年3月开始给单位开发<机关规范化管理网络平台>,10月底成功上线运行,但是存在一个bug: 部署环境: apache tomcat 6.0.41 + mysql5.5 + jbpm ...

  8. 062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用

    062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用 本文知识点:二维数组应用 二维数组的声明和创建 ? 出现空指针异常 数组的名字指向数组的第 ...

  9. DoModal 函数的用法

    转载:https://blog.csdn.net/mpp_king/article/details/79707728                        https://www.cnblog ...

  10. javaFX 在窗口的标题栏显示当前时间,1秒更新一次时间

    例1:在窗口的标题栏显示当前时间,1秒更新一次时间 1 import java.text.DateFormat; 2 import java.text.SimpleDateFormat; 3 impo ...