C 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中编写动态调用代码即可。
不用做其他任何连接和导入头文件的操作。
运行成功。
c语言中库的定义等相关概念 -回复

c语言中库的定义等相关概念-回复C语言中的库(Library)是指一组预先编写好的可重用的代码,这些代码包含了各种功能,如输入输出、字符串处理、数学运算等。
库可以被其他程序调用,以提高开发效率和代码复用性。
本文将逐步解释库的定义,库的类型,库的使用和实现等相关概念。
定义:库是一种软件资源,其中包含了预先编写好的可重用的代码。
这些代码经过测试和优化,以提供特定功能或解决特定问题。
库可以作为单个文件或多个文件的集合提供。
C语言中的库分为两种类型:静态库和动态库。
库的类型:1. 静态库(Static Library):静态库也称为静态链接库,它在编译时被链接到可执行文件中。
静态库包含了预编译好的目标代码,这些代码可以直接在编译阶段与程序的其他模块进行链接。
静态库的优点是可移植性强,不依赖于特定的运行环境。
然而,静态库的缺点是占用磁盘空间较大,每个可执行文件都会包含一份完整的库代码。
2. 动态库(Dynamic Library):动态库也称为共享库或动态链接库,它在程序运行时被加载到内存中。
动态库的代码可以被多个程序共享,从而节省了系统资源。
动态库的优点是占用磁盘空间较小,可以在运行时动态加载和卸载。
然而,动态库的缺点是可能会导致版本兼容性问题和依赖关系管理较为复杂。
库的使用:使用库的步骤如下:1. 引入头文件(Include Header File):在需要使用库中函数或变量的源代码文件中,通过#include指令包含库的头文件。
头文件包含了库中函数和变量的声明。
示例代码如下:c#include <stdio.h>2. 链接库文件(Link Library File):在编译可执行文件时,需要将库的目标代码与程序的其他模块进行链接。
对于静态库,可以使用编译器提供的静态链接选项进行链接。
对于动态库,可以使用编译器提供的动态链接选项进行链接。
示例代码如下:gcc main.c -lmath 链接静态库gcc main.c -lmath 链接动态库3. 调用库中的函数(Call Functions):在源代码文件中,可以通过函数名直接调用库中的函数,并传递参数。
动态链接库.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,可以看到它是如何调用动态库中的函数的。
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的可执⾏⽂件。
CSharp调用C动态链接库详解

第一篇编译C的动态连接库在实际工作中,我们经常会将C语言中的.lib和.h文件(静态库)编译成动态连接库.dll 文件(这里只提供这两种文件,没有完整的工程),以提供给其他语言平台调用。
1,必须有.lib文件,只有.h文件是无法编译动态连接库的。
2,我使用的是VS2008,这里打开VS,新建项目—〉win32控制台应用程序,输入项目名称,点击确定,图示如fig.1所示。
Fig.13,点击下一步,依次如图fig.2-3所示,最后点击完成,就会生成一个带有.cpp的文件。
Fig.2Fig.34,打开项目—属性—配置属性—链接器—输入,如下图fig.4所示,在附加依赖项中加入你要添加的.lib文件,如果有一些系统.lib库没有添加或出现错误,可以在忽略特定库中添加该库。
注意:如果编译的dll文件调用中出现“xx.dll中找不到函数xx的入口点”,很有可能是一个xx.def文件没有添加,该文件的内容是EXPORTS 函数名@+序号。
如果这个文件中没有你要调用的API 函数,那么你在C#中是调用不到这个函数的,同时这个文件你可以同坐记事本自己编辑,注意Fig.45,在.cpp文件中添加.h文件的引用,不需要把所有的.h文件都引用进去,只需要.lib 文件入口相关的.h文件。
6,最后把.lib和.h文件拷贝到工程debug目录里,生成解决方案就Ok了,你会发现.dll 在debug目录中出现。
第二篇C#调用C/C++的动态连接库1,清楚C++与C#类型对应关系,即调用关系:C基本类型对照关系----VS2008:除此之外,c++:HANDLE(void *) ---- c#:System.IntPtrc++:WORD(unsigned short) ---- c#:System.UInt16c++:DWORD(unsigned long) ---- c#:System.UInt32c++:结构体 ---- c#:public struct 结构体{};c++:结构体 &变量名 ---- c#:ref 结构体变量名c++:结构体 **变量名 ---- c#:outc++:GUID ---- c#:Guidc++:UINT8 * ---- c#:ref bytec++:char*/void*(指向一个字符串) ---- c#:string对于结构体中的指针数组,对应于C#中的IntPtr[]类型,如:int * a[] -------------- IntPtr[]a2,清楚在C#中调用C/C++.dll文件的一般格式using System.Runtime.InteropServices; //必须引用的命名空间[DllImport("user32.dll")]public static extern ReturnType FunctionName(type arg1,type arg2,...);//必须定义为类的静态外部的方法3,[DllImport(参数)]设定①“xx.dll”:dll文件名字②CharSet :控制调用函数的名称版本及指示如何向方法封送 String 参数。
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语言调用pybind11生成的动态链接库

C语⾔调⽤pybind11⽣成的动态链接库简介C 语⾔调⽤ pybind11 ⽣成的动态链接库?这是什么需求?脱裤⼦放屁?因为要在 python ⾥⾯可以调⽤ C 语⾔的代码,所以要⽤ pybind11 ⽣成可以被 python 调⽤的动态链接库。
可是,现在竟然有这种奇怪的需求,竟然要调⽤这个动态链接库!不管你的需求是哪⾥来的,如果有这个需求,看这篇就对了。
⽹上的讨论⼏乎没有,毕竟谁会这么⼲啊。
这篇博客先介绍 pybind11 ⽣成动态链接库,然后再讲如何调⽤.pybind11 ⽣成动态链接库⽤下⾯的代码,可以编译⽣成⼀个 pybind11 动态链接库。
在 python ⾥⾯可以调⽤。
#include <pybind11/pybind11.h>#include "example.h"int add(int i, int j) {return i + j;}PYBIND11_MODULE(example, m) {m.doc() = "pybind11 example plugin"; // optional module docstringm.def("add", &add, "A function which adds two numbers");}调⽤下⾯的命令,来⽣成动态链接库。
g++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)在当前⽬录下⾯,会⽣成⼀个 example.cpython-38-x86_64-linux-gnu.so。
这时就可以使⽤ python 调⽤上⾯的 add 函数了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C/C++中动态链接库的创建和调用
1.动态链接库的创建步骤:
创建Non-MFC DLL动态链接库
1.打开File —> New —> Project选项,选择Win32 Dynamic-Link Library —>sample project —>工程名:DllDemo
2.新建一个.h文件DllDemo.h 并添加如下代码:
#ifdef DllDemo_EXPORTS
#define DllAPI _declspec(dllexport)
#else
#define DllAPI _declspec(dllimport)
extern “C” // 原样编译
{
DllAPI int _stdcall Max(int a,int b); //_stdcall使非C/C++语言内能够调用API
}
#endif
3.新建一个.cpp文件,并添加如下代码
#include "DllDemo.h"
DllAPI int __stdcall Max(int a,int b)
{
if(a==b) return NULL;
else if(a>b) return a;
else return b;
}
4.编译程序生成动态链接库
1.2 用.def文件创建动态连接库DllDemo.dll
1、删除DllDemo工程中的DllDemo.h文件。
2、在DllDemo.cpp文件头,删除#include DllDemo.h语句。
3、向该工程中加入一个文本文件,命名为DllDemo.def并写入如下语句:
LIBRARY MyDll
EXPORTS
Max@1
4、编译程序生成动态连接库。
2.动态链接库的调用步骤
2.1 隐式调用
1.建立DllCnsTest工程
2.将文件DllDemo.dll、DllDemo.lib拷贝到DllCnsTest工程所在的目录
3.在DllCnsTest中添加如下语句:
#define DllAPI _declspec(dllimport)
#pragma comment(lib,”DllDemo.lib”)
extern “C”
{
DllAPI int _stdcall Max(int a,int b);
}
4.在DllCnsTest.cpp文件中添加如下语句:
#include “DllCnsTest.h”//或者#include “DllDemo.h”
void main()
{
int value;
value = Max(2,9);
printf(“The Max value is %d\n”,value);
}
5.编译并生成应用程序DllCnsTest.exe
2.2显示调用
1、建立DllWinTest工程。
2、将文件DllDemo.dll拷贝到DllWinTest工程所在的目录或Windows系统目录下。
3、用vc/bin下的Dumpbin.exe的小程序,查看DLL文件(DllDemo.dll)中的函数结构。
4、使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针。
例:typedef int(*lpMax)(int a,int b); //此语句可以放在.h文件中
5、通过LoadLibray()将Dll加载到当前的应用程序中并返回当前Dll文件的句柄。
例:HINSTANCE hDll; //声明一个Dll实例文件句柄
hDll = LoadLibrary("DllDemo.dll");//导入DllDemo.dll动态连接库
注意:如果加载失败的话,改为:hDll = LoadLibrary(TEXT("DllDemo.dll"));
原因:LoadLibrary实际使用了LoadLibraryW而非LoadLibraryA,因此需要UNICODE字符串(宽字符串),而非窄字符串。
如下:
#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#else
#define LoadLibrary LoadLibraryA
#endif // !UNICODE
在C/C++代码中,直接使用""定义的字符串为窄字节串,而windows头文件中提供的TEXT宏可以根据是否定义了UNICODE宏来自动选择字符串类型。
因此,利用TEXT宏使其自动选择了正确的字符集,dll调用成功。
PS:LoadLibrary函数跟LoadLibraryEx函数装载dll的机制不一样,前者在装载dll遇到与该dll依赖的其他dll时会自动装载,而后者不会,网上有加载自己的dll无法成功的例子,排除路径问题的话(最好全路径),就要考虑该dll是否依赖到其它的dll。
6、通过GetProAddress()函数获取导入到应用程序中的函数指针。
例:lpMax Max;
Max = (lpMax)GetProAddress(hDll,”Max”);
int value;
value = Max(2,9);
printf(“The Max value is %d”,value);
7、函数调用完毕后,使用FreeLibrary()写在Dll文件。
FreeLibrary(hDll);
8、编译并生成应用程序DllWinTest.exe
注:显示链接应用程序编译时不需要使用相应的Lib文件。