c语言创建dll以及使用
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以及使用的更多相关文章
- C语言创建并使用dll
利用C语言创建 利用 C++使用: 参见前面 利用C语言创建并使用lib 如法炮制创建 showDll Dll代码 __declspec(dllexport) double myDivision(i ...
- Visual Studio 2019 使用C语言创建动态链接库(Dll)并使用C语言和C#实现调用
参考网址:https://blog.csdn.net/weixin_34976988/article/details/99625533 一.创建DLL1.建立动态链接库项目 2.创建头文件和源文件 删 ...
- 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试
from:http://m.blog.csdn.net/article/details?id=51075023 在VS2015中先创建C#项目,然后再创建要编写的动态库DLL项目,这样做的好处是整个解 ...
- VC++2008 用空工程创建 DLL
VC++2008 用空工程创建 DLL 一.创建 DLL 工程项目: 1)点击菜单[File] -> [New] -> [Project...] 弹出 “New Project” 对话框: ...
- 在VS2015中用C++创建DLL并用C++调用且同一时候实现对DLL的调试
一:用C++创建DLL 依照[在VS2015中用C++编写可被其他语言调用的动态库DLL]提示创建C++编写的DLL.或參考[在VS2015中用C++创建DLL并用C#调用且同一 ...
- C#创建dll类库
类库让我们的代码可复用,我们只需要在类库中声明变量一次,就能在接下来的过程中无数次地使用,而无需在每次使用前都要声明它.这样一来,就节省了我们的内存空间.而想要在类库添加什么类,还需取决于类库要实现哪 ...
- 创建dll教程
先看我的总结: 总结: 1.头文件中如果想以C形式提供,要判断,如果定义了 _cplusplus, extern "c"{ 这里写接口声明 } 2.接口声明中,要表明接口接入点的 ...
- Java JNI调用c语言的dll测试
最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下: 环境:windows 10(64位) + JDK(32位,版本1.7.0 ...
- windows编程:创建DLL
创建DLL Dll是动态链接库的缩写,可以作为附加代码动态映射到进程的地址空间中. 动态库的一般创建方法如下 方法1.使用 __declspec(dllexport) 方式导出 一般的框架如下 // ...
随机推荐
- synchronized和lock的作用与对比
一.synchronized的作用 synchronized是java中的一个关键字,用于线程同步.1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象 ...
- 有关java反射的几个小方法的作用和区别
1.Class类中 getXXX()和getDeclaredXXX()的作用和区别: 前者获取某个类的所有公共(public)的字段(or方法or构造函数),包括父类.后者获取所有的字段(or方法or ...
- redis发布订阅客户端报错
转自简书[https://www.jianshu.com/p/a85ec38245da] 最近遇到一个问题,springBoot程序中有一个监听器,监听redis中发来的消息(其实是监听一个key的消 ...
- sping ioc 源码分析(一)-- register(componentClasses) 方法
一.测试环境的搭建: public class Apple { } @Component public class MyComponet { } public class MyCondition im ...
- 基于Scrapy的交互式漫画爬虫
Github项目地址 前言 该项目始于个人兴趣,本意为给无代码经验的朋友做到能开箱即用 阅读此文需要少量Scrapy,PyQt 知识,全文仅分享交流 摘要思路,如需可阅读源码,欢迎提 issue 一. ...
- python3 连接数据库~
~目前记录的是针对python3写的数据库连接,不适用于pyhon2.python3如果想要与数据库进行连接,则需要先下载对应各数据库的插件包,然后导入包.python3的插件下载地址:https:/ ...
- const pointers
1 指针 p对应的地址是常量,但是里面存放的data不是常量 2 地址里存放的data是常量,但是地址不是常量 3 地址和指针都是常量
- Mice and Rice(queue的用法)
Mice and Rice(queue的用法) Mice and Rice is the name of a programming contest in which each programmer ...
- spring-boot-route(五)整合Swagger生成接口文档
目前,大多数公司都采用了前后端分离的开发模式,为了解决前后端人员的沟通问题,后端人员在开发接口的时候会选择使用swagger2来生成对应的接口文档,swagger2提供了强大的页面调试功能,这样可以有 ...
- DX12龙书 01 - 向量在几何学和数学中的表示以及运算定义
0x00 向量 向量 ( vector ) 是一种兼具大小 ( magnitude ) 和方向的量. 0x01 几何表示 几何方法中用一条有向线段来表示一个向量,其中,线段长度代表向量的模,箭头的指向 ...