演练:创建和使用动态链接库 (C++)
使用CLion创建C语言动态链接库DLL文件

参考
准备
配置编译环境MinGW,类似配置IDEA的jdk
配置构建环境Cmake
调试结果如下
创 建 DLL项 目
项目名称为testdll
项 目 stdll.dll
创 建 DLL使 用 项 目
使用C语言调用dll
在项目下创建lib目录,将之前生成的libtestdll.dll文件放到此目录下,设置lib搜索目录。
其实短链接只有生成和跳转还不能满足实际业务需求还需要考虑其使用场景目前短链接使用场景主要是短信内带短链接
使用 CLion创建 C语言动态链接库 DLL文件
前言
CLion是JetBrains公司一款开发C和C++的强大IDE,其公司产品还有IntelliJ IDEA,WebStorm,Pycharm等。 MinGW 的全称是:Minimalist GNU on Windows,可以看做 GCC 的 Windows 版本。 DLL 的全称为 Dynamic Link Library,动态链接库,类似java中的jar包,达到代码复用的优势。
MFC动态链接库的创建和调用(类和函数的dll导出和调用)

1.新建MFC DLL工程,取名为:DLL0410
动态链接库的创建和调用(类,函数的DLL导出和调用)
2.在工程中编辑好DLL0410.h,DLL0410.cpp,DLL0410.def三个文件后编译生成对应的dll和lib文件
2.1 DLL0410.h
2.2 DLL0410.cpp
2.3 DLL0410.def
2.4 编辑好上面的3个文件编译后,用dumpbin命令查看是否有函数导出。
(如图所示,sub全局函数和add类的成员函数已经导出)
3.新建一个工程DLL0410test将生成的DLL0410.dll,DLL0410.lib以及DLL0410.h文件拷贝到 DLL0410test工程目录下
4.静态调用:在工程的DLL0410test.cpp文件中导入头文件DLL0410.h,并编写对应的静态调用代码。
同时也要在工程属性链接中加入DLL0410.lib文件。
(如果编译出错有可能是,工程属性中的常规>>字符集>>修改为 使用多字节字符集)
运行成功
5.4.动态调用:只需将生成的DLL0410.dll文件拷贝到新建工程目录下,直接在工程的
DLL0410test.cpp中编写动态调用代码即可。
不用做其他任何连接和导入头文件的操作。
运行成功。
动态链接库.so的编译与使用

动态链接库*.so的编译与使用- -动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。
1、动态库的编译下面通过一个例子来介绍如何生成一个动态库。
这里有一个头文件:so_test.h,三个.c文件:test_a.c、t est_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。
so_test.h:#include <stdio.h>#include <stdlib.h>void test_a();void test_b();void test_c();test_a.c:#include "so_test.h"void test_a(){printf("this is in test_a...\n");}test_b.c:#include "so_test.h"void test_b(){printf("this is in test_b...\n");}test_c.c:#include "so_test.h"void test_c(){printf("this is in test_c...\n");}将这几个文件编译成一个动态库:libtest.so$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so2、动态库的链接在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。
程序的源文件为:test.c。
test.c:#include "so_test.h"int main(){test_a();test_b();test_c();return 0;}l 将test.c与动态库libtest.so链接生成执行文件test:$ gcc test.c -L. -ltest -o testl 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了$ ldd test./test 执行test,可以看到它是如何调用动态库中的函数的。
VC6.0中,创建、调用 dll

[动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。
DLL 还有助于共享数据和资源。
多个应用程序可同时访问内存中单个DLL 副本的内容。
动态链接库(Dynamic Link Library或者Dynamic-link library,缩写为DLL),是微软公司在微软视窗操作系统(即Windows操作系统)中实现共享函数库概念的一种方式。
这些库函数的扩展名是.DLL、.OCX(包含ActiveX控制的库)或者.DRV(旧式的系统驱动程序)。
动态链接库缩写为DLL,在电脑中可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。
例如,您有一个大型网络游戏,如果把整个数百MB 甚至数GB的游戏的代码都放在一个应用程序里,日后的修改工作将会十分费时,而如果把不同功能的代码分别放在数个动态链接库(DLL)中,您无需重新生成或安装整个程序就可以应用更新。
]1.使用VC6.0 生成DLL新建项目“Win32 Dynamic-Link Library”,输入项目名称,确定后选择“A simple DLL project”点击“完成”。
以下为cpp文件自动生成的代码:#include "stdafx.h"BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){return TRUE;}编辑cpp文件:在#include "stdafx.h"的下一行加入extern "C" __declspec(dllexport) int fun(int a, int b);/*这是C格式导出函数;这种写法一般用在C++写的DLL中,指按C的规则导出这个函数,否则导出的函数会很怪; 加上extern "C" 表示按标准C格式导出函数.如果去掉仅兼容C++;其中int fun(int a, int b) 这部分代码是我们想用dll 实现的函数原型声明如果还想加入其他的可以继续加入extern "C" __declspec(dllexport) int fun1(int a, int b);*/DllMain 是DLL 的默认入口函数,类似于C语言的main函数,该例子无需修改此处,在DllMain 的后面加入:int fun(int a,int b){return a+b;}这就是我们想用DLL 实现的函数的定义,build 之后就会在debug 目录下生成我们想要的dll 文件2.调用DLL新建一个Win32 Console Application 工程,把刚才生成的dll 文件拷贝到工程的根目录下在stdafx.h 文件中加入:#include <windows.h>编辑cpp文件:#include "stdafx.h"typedef int (*PFUN)(int,int);void main(){HMODULE hModule = ::LoadLibrary("dlltest.dll");PFUN newfun = (PFUN)::GetProcAddress(hModule,"fun");int i = newfun(1,2);printf("The result is %d\n",i);::FreeLibrary(hModule);}然后,运行就可以看到结果了转VC6.0下调用Dll文件提供的函数接口和全局变量函数接口:首先把生成的Dll文件(如RegularDll.dll和RegularDll.lib)拷贝到当前工程所在文件夹,调用有两种方法:1)动态方法:使用LoadLibrary和GetProcAddress等函数,例typedef void (*lpFun)(void);HINSTANCE hDll;hDll = LoadLibrary("RegularDll.dll");if (NULL==hDll) {MessageBox("Dll load failed!");}lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"ShowDlg");if (NULL == pShowDlg) {MessageBox("Load function \"ShowDlg\" failed!");}pShowDlg();*/2)静态声明方法:创建Dll的工程中,函数声明和定义时用_stdcall 修饰,例void _stdcall ShowDlg(void){...}在调用dll的工程的文件中,在文件头部声明库和函数,如下例#pragma comment(lib,"RegularDll.lib")void _stdcall ShowDlg(void);调用时直接ShowDlg()就可以了。
C#调用动态库,C_调用C++DLL

同上面一样,我们也举一个例子: int __stdcall FunctionName(unsigned char ¶m1, unsigned char *param2) 在 C#中对其进行调用的方法是: [DllImport(“ COM DLL path/file ”)] extern static int FunctionName(ref byte param1, ref byte param2) 看到这,可能有人会问,&是取地址,*是传送指针,为何都只用 ref 就可以了呢?一种可能的解释是 ref 是一个具有重载特性的修饰符,会自动识别是取地址还是传送指针。 在实际的情况中,我们利用参数传递地址更多还是用在传送数组首地址上。 如:byte[] param1 = new param1(6); 在这里我们声明了一个数组,现在要将其的首地址传送过去,只要将 param1 数组的第一个元素用 ref 修 饰。具体如下: [DllImport(“ COM DLL path/file ”)] extern static int FunctionName(ref byte param1[1], ref byte param2)
第四步,修改动态链接库实现,实现整数参数的输出: LIBEXPORT_API int mySum(int a,int b,int *c) { *c=a+b; return *c;
(此文详细解说了,C#调用 C++DLL 的参数传入,与传出,sting 类型的传出等) C#调用 C++编写的 COM DLL 封装库时会出现两个问题: 1. 数据类型转换问题 2. 指针或地址参数传送问题 首先是数据类型转换问题。因为 C#是.NET 语言,利用的是.NET 的基本数据类型,所以实际上是 将 C++的数据类型与.NET 的基本数据类型进行对应。 例如 C++的原有函数是: int __stdcall FunctionName(unsigned char param1, unsigned short param2) 其中的参数数据类型在 C#中,必须转为对应的数据类型。如: [DllImport(“ COM DLL path/file ”)] extern static int FunctionName(byte param1, ushort param2) 因为调用的是__stdcall 函数,所以使用了 P/Invoke 的调用方法。其中的方法 FunctionName 必须声明为 静态外部函数, 即加上 extern static 声明头。 我们可以看到,在调用的过程中, unsigned char 变为了 byte, unsigned short 变为了 ushort。变换后,参数的数据类型不变,只是声明方式必须改为.NET 语言的规范。 我们可以通过下表来进行这种转换: Win32 Types char, INT8, SBYTE, CHAR short, short int, INT16, SHORT int, long, long int, INT32, LONG32, BOOL , INT __int64, INT64, LONGLONG unsigned char, UINT8, UCHAR , BYTE unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT unsigned __int64, UINT64, DWORDLONG, ULONGLONG float, FLOAT double, long double, DOUBLE CLR Type System.SByte System.Int16 System.Int32 System.Int64 System.Byte Sys.UInt64 System.Single System.Double
Windows下C语言调用dll动态链接库

Windows下C语⾔调⽤dll动态链接库dll是windows下的动态链接库⽂件,下⾯记录⼀下在windows下如何调⽤C语⾔开发的dll动态链接库。
1.dll动态链接库的源代码hello_dll.c#include "stdio.h"_declspec(dllexport) void test_print(char const *str){printf("%s\n", str);}_declspec(dllexport) int test_add(int a, int b){return a + b;}上⾯的代码定义了两个函数,第⼀个函数需要传⼊⼀个字符串,然后打印出这个字符串,第⼆个函数需要转⼊两个int型整数,然后返回这两个整数的和。
执⾏ cl -LD hello_dll.c 会⽣成hello_dll.dll⽂件2.main函数的源代码test_hello_dll.c#include <stdlib.h>#include <windows.h>int main(int argc, char const *argv[]){// define two functional pointervoid(*p_test_print)(char const *) = NULL;int(*p_test_add)(int, int) = NULL;int add_result;// load dll file, require window.h fileHMODULE module = LoadLibraryA("hello_dll.dll");if (module == NULL) {system("error load");}p_test_print = (void(*)(char const *))GetProcAddress(module, "test_print");p_test_add = (int(*)(int, int))GetProcAddress(module, "test_add");if (p_test_print != NULL) {p_test_print("Hello This is from dll");} else {system("function p_test_print can not excute");}if (p_test_add != NULL) {add_result = p_test_add(5, 5);printf("Add result is %d\n", add_result);} else {system("function p_test_print can not excute");}FreeLibrary(module);system("pause");return0;}执⾏ cl test_hello_dll.c 会⽣成test_hello_dll.exe的可执⾏⽂件。
VC++ 2017 动态链接库的创建和使用总结

Visual studio c++ 2017 动态链接库的创建和使用总结一动态链接库的创建两种方式:1、只有从文件->新建->项目->Windows桌面-> Windows桌面向导->选择“动态链接库(.dll)->生成解决方案,才会生成.dll和.lib文件。
(1)在头文件声明中(注意要在头文件变量和函数声明中,而不是在变量和函数的定义中声明),不加extern “C”修饰,编译成DLL后,用depends.exe查看导出函数名。
可以看出,导出的函数名都被编译器篡改了。
(2)在头文件声明中,变量和函数名前加extern “C”修饰后,编译成DLL后,再用depends.exe查看导出函数名。
可以看出,用extern “C”修饰的函数名,编译后函数名保持不变。
类及成员函数不能用extern “C”修饰,编译成DLL后,成员函数名发生了改变。
2、如果从文件->新建->项目->动态链接库(DLL)->生成解决方案,就只生成.dll,不生成.lib。
二动态链接库的调用两种方式:1、显式调用(1)使用显式调用的前提:创建的DLL,编译时不要篡改函数名称,定义函数名时,可用extern “C”修饰函数名,保证编译时,函数名不被篡改。
否则GetProcAddress( )不能正确地获取dll中的函数名。
但是导出的类不能使用extern “C”修饰。
(2)使用显式调用的优点:不用动态链接库的.h和.lib文件,只要有.dll文件就可调用库函数,使用LoadLibrary(),在需要调用.dll中的库函数时,才动态加载到内存中,使用完毕后,可以用FreeLibrary()释放内存中的dll;使用GetProcAddress( )获取dll中的函数名。
必须事先知道dll中的函数名和形式参数。
(3)使用显式调用缺点:调用每个函数时,都必须使用 GetProcAddress( )获取dll中的函数名,并转换成原来的函数,比较麻烦。
c语言dll写法

c语言dll写法
在C语言中,编写DLL(动态链接库)的基本步骤如下:
1. 定义导出函数或变量:使用__declspec(dllexport)关键字将需要导出的函数或变量声明为导出符号。
例如:
```c
__declspec(dllexport) void MyFunction()
{
// 函数实现
}
```
2. 编译源代码:使用C编译器将源代码编译为目标文件。
例如,使用GCC 编译器可以使用以下命令:
```shell
gcc -c -DBUILD_DLL
```
这将生成一个名为的目标文件。
3. 创建DLL项目:使用链接器将目标文件链接为DLL。
例如,使用GCC编译器可以使用以下命令:
```shell
gcc -shared -o
```
这将生成一个名为的DLL文件。
4. 使用DLL:在其他C语言程序中,使用__declspec(dllimport)关键字导
入DLL中的导出符号。
例如:
```c
__declspec(dllimport) void MyFunction();
```
然后在程序中使用该函数或变量即可。
注意,在使用DLL时需要确保DLL
文件与应用程序位于同一目录中,或者在系统路径中添加DLL文件的路径。
以上是编写C语言DLL的基本步骤。
需要注意的是,具体的实现方式可能
会因编译器和操作系统而有所不同。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Visual C++ 指导教程演练:创建和使用动态链接库(C++)Visual Studio 2010其他版本0(共1)对本文的评价是有帮助评价此主题我们将创建的第一种类型的库是动态链接库(DLL)。
使用DLL 是一种重用代码的绝佳方式。
您不必在自己创建的每个程序中重新实现同一例程,而只需对这些例程编写一次,然后从需要该功能的应用程序引用它们即可。
本演练涵盖以下内容:∙创建新的动态链接库(DLL) 项目。
∙向动态链接库添加类。
∙创建引用动态链接库的应用程序。
∙在控制台应用程序中使用类库的功能。
∙运行应用程序。
系统必备本主题假定您具备C++ 语言的基础知识。
如果您是刚开始学习C++,建议您参阅Herb Schildt 编写的“C++ Beginner's Guide”(《C++ 初学者指南》),该书可从/fwlink/?LinkId=115303在线获得。
创建新的动态链接库(DLL) 项目1.从“文件”菜单中,选择“新建”,然后选择“项目…”。
2.在“项目类型”窗格中,选择“Visual C++”下的“Win32”。
3.在“模板”窗格中,选择“Win32 控制台应用程序”。
4.为项目选择一个名称,如MathFuncsDll,并将其键入“名称”字段。
为解决方案选择一个名称,如DynamicLibrary,并将其键入“解决方案名称”字段。
5.单击“确定”启动Win32 应用程序向导。
在“Win32 应用程序向导”对话框的“概述”页中,单击“下一步”。
6.在“Win32 应用程序向导”中的“应用程序设置”页中,选择“应用程序类型”下的“DLL”(如果可用),或者选择“控制台应用程序”(如果“DLL”不可用)。
某些版本的Visual Studio 不支持通过使用向导创建DLL 项目。
您可以稍后对此进行更改,以将项目编译为DLL。
7.在“Win32 应用程序向导”的“应用程序设置”页中,选择“附加选项”下的“空项目”。
8.单击“完成”创建项目。
向动态链接库添加类1.若要为新类创建头文件,请从“项目”菜单中选择“添加新项…”。
将显示“添加新项”对话框。
在“类别”窗格中,选择“Visual C++”下的“代码”。
在“模板”窗格中选择“头文件(.h)”。
为头文件选择一个名称,如MathFuncsDll.h,并单击“添加”。
将显示一个空白文件。
2.添加一个名为“MyMathFuncs”的简单类,以执行常见的算术运算,如加、减、乘和除。
代码应与以下内容类似:复制// MathFuncsDll.hnamespace MathFuncs{class MyMathFuncs{public:// Returns a + bstatic __declspec(dllexport) double Add(double a, doubleb);// Returns a - bstatic __declspec(dllexport) double Subtract(double a, dou ble b);// Returns a * bstatic __declspec(dllexport) double Multiply(double a, dou ble b);// Returns a / b// Throws DivideByZeroException if b is 0static __declspec(dllexport) double Divide(double a, double b);};}3.请注意此代码方法声明中的__declspec(dllexport)修饰符。
这些修饰符使DLL 能够导出该方法以供其他应用程序使用。
有关更多信息,请参见dllexport, dllimport。
4.若要为新类创建源文件,请从“项目”菜单中选择“添加新项…”。
将显示“添加新项”对话框。
在“类别”窗格中,选择“Visual C++”下的“代码”。
在“模板”窗格中,选择“C++ 文件(.cpp)”。
为源文件选择一个名称,如MathFuncsDll.cpp,并单击“添加”。
将显示一个空白文件。
5.在源文件中实现“MyMathFuncs”的功能。
代码应与以下内容类似:复制// MathFuncsDll.cpp// compile with: /EHsc /LD#include "MathFuncsDll.h"#include <stdexcept>using namespace std;namespace MathFuncs{double MyMathFuncs::Add(double a, double b){return a + b;}double MyMathFuncs::Subtract(double a, double b){return a - b;}double MyMathFuncs::Multiply(double a, double b){return a * b;}double MyMathFuncs::Divide(double a, double b){if (b == 0){throw new invalid_argument("b cannot be zero!");}return a / b;}}6.若要将项目生成为DLL,请从“项目”菜单中选择MathFuncsDll“属性...”。
在左窗格中,选择“配置属性”下的“常规”。
在右窗格中,将“配置类型”更改为“动态库(.dll)”。
单击“确定”保存更改。
注意如果您从命令行生成项目,请使用/LD编译器选项指定输出文件应为DLL。
有关更多信息,请参见/MD、/MT、/LD(使用运行库)。
7.编译该动态链接库,方法是选择“生成”菜单中的“生成解决方案”。
这样就创建了一个可供其他程序使用的DLL。
有关DLL 的详细信息,请参见DLL。
创建引用动态链接库的应用程序1.若要创建将引用并使用刚创建的动态链接库的应用程序,请从“文件”菜单中选择“新建”,然后选择“项目...”。
2.在“项目类型”窗格中,选择“Visual C++”下的“Win32”。
3.在“模板”窗格中,选择“Win32 控制台应用程序”。
4.为项目选择一个名称(如MyExecRefsDll),并将其键入“名称”字段。
从“解决方案”旁边的下拉列表中选择“添入解决方案”。
这会将新项目添加到该动态链接库所属的同一个解决方案中。
5.单击“确定”启动“Win32 应用程序向导”。
在“Win32 应用程序向导”对话框的“概述”页中,单击“下一步”。
6.在“Win32 应用程序向导”的“应用程序设置”页中,选择“应用程序类型”下的“控制台应用程序”。
7.在“Win32 应用程序向导”的“应用程序设置”页中,清除“附加选项”下的“预编译头”复选框。
8.按“完成”创建项目。
在控制台应用程序中使用类库的功能1.创建新的控制台应用程序后,将为您创建一个空程序。
源文件的名称与您在前面为项目选择的名称相同。
在本示例中,名为“MyExecRefsDll.cpp”。
2.若要使用在动态链接库中创建的算术例程,则必须引用该库。
若要执行此操作,请在解决方案资源管理器中选择MyExecRefsDll 项目,然后从“项目”菜单中选择“引用...”。
在“属性页”对话框中,展开“通用属性”节点,选择“框架和引用”,然后选择“添加新引用...”按钮。
有关“引用...”对话框的更多信息,请参见“<Projectname> 属性页”对话框->“通用属性”->“框架和引用”。
3.显示“添加引用”对话框。
此对话框列出了所有可以引用的库。
“项目”选项卡列出了当前解决方案中的所有项目,以及它们包含的所有库。
在“项目”选项卡中,选择MathFuncsDll。
然后单击“确定”。
4.若要引用动态链接库的头文件,必须修改包含目录路径。
为此,请在“属性页”对话框中展开“配置属性”节点,然后展开“C/C++”节点,并选择“常规”。
在“附加包含目录”旁边,键入MathFuncsDll.h 头文件所在位置的路径。
5.可执行文件仅在运行时加载动态链接库。
必须告诉系统在哪里查找“MathFuncsDll.dll”。
您可以通过使用PATH环境变量做到这一点。
为此,请在“属性页”对话框中展开“配置属性”节点,并选择“调试”。
在“环境”旁边键入以下内容:PATH=<MathFuncsDll.dll文件的路径>,其中<MathFuncsDll.dll文件的路径> 应替换为MathFuncsDll.dll 的实际位置。
单击“确定”保存所有更改。
注意如果要从命令行而不是从Visual Studio 运行可执行文件,则必须在命令提示符处手动更新PATH 环境变量,如下所示:set PATH=%PATH%;<MathFuncsDll.dll文件的路径>,其中<MathFuncsDll.dll文件的路径> 应替换为MathFuncsDll.dll 的实际位置。
6.现在,可以在应用程序中使用“MyMathFuncs”类了。
使用以下代码替换“MyExecRefsDll.cpp”的内容:复制// MyExecRefsDll.cpp// compile with: /EHsc /link MathFuncsDll.lib#include <iostream>#include "MathFuncsDll.h"using namespace std;int main(){double a = 7.4;int b = 99;cout << "a + b = " <<MathFuncs::MyMathFuncs::Add(a, b) << endl;cout << "a - b = " <<MathFuncs::MyMathFuncs::Subtract(a, b) << endl;cout << "a * b = " <<MathFuncs::MyMathFuncs::Multiply(a, b) << endl;cout << "a / b = " <<MathFuncs::MyMathFuncs::Divide(a, b) << endl;return 0;}7.通过从“生成”菜单中选择“生成解决方案”,生成可执行文件。