C C++动态链接库的创建与调用
- 格式:doc
- 大小:33.50 KB
- 文档页数:2
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语言中的库(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在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动态链接库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的可执⾏⽂件。
第一篇编译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 参数。
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 ⽣成的动态链接库?这是什么需求?脱裤⼦放屁?因为要在 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 函数了。
如何用VC创建及调用DLL使用Visual C++(VC++)创建和调用动态链接库(DLL)可以提供一种模块化的方式来组织和重用代码。
本文将介绍如何使用VC++创建DLL,并在另一个VC++项目中调用该DLL。
创建DLL以下是使用VC++创建DLL的步骤:1.打开VC++,在“文件”菜单中选择“新建”->“项目”。
2. 在“新建项目”对话框中,选择“Win32控制台应用程序”。
点击“下一步”。
3.输入项目名称,并选择项目位置,点击“下一步”。
4.在“应用程序类型”对话框中,选择“DLL”并取消勾选“预编译头”。
点击“下一步”。
5.在“进入代码”对话框中,选择“空项目”。
点击“完成”。
6. 创建一个新的源文件,例如“MyDLL.cpp”。
7. 在“MyDLL.cpp”中,编写所需的函数并导出。
例如:```C++#include <Windows.h>// 导出的函数需要使用__declspec(dllexport)修饰extern "C" __declspec(dllexport) int AddNumbers(int a, int b) return a + b;```8. 在项目属性中,选择“链接器”->“高级”,将“入口点”设置为“DllMain”。
9.在“生成”菜单中选择“生成解决方案”,以生成DLL文件。
以下是在VC++项目中调用DLL的步骤:1.打开VC++,在“文件”菜单中选择“新建”->“项目”。
2. 在“新建项目”对话框中,选择“Win32控制台应用程序”。
点击“下一步”。
3.输入项目名称,并选择项目位置,点击“下一步”。
4.在“应用程序类型”对话框中,选择“控制台应用程序”并取消勾选“预编译头”。
点击“下一步”。
5.在“附加选项”对话框中,勾选“空项目”。
点击“完成”。
6.将之前生成的DLL文件复制到新项目的文件夹中。
7.在项目属性中,选择“C/C++”->“常规”,将“附加包含目录”设置为包含DLL文件的文件夹路径。
MFC创建动态链接库DLL并调⽤⽅法详解实例⼀:1、创建⼀个动态链接库⼯程,如login_dll。
2、在原⼯程头⽂件或者新建头⽂件如showdlg.h定义动态链接库的导出函数,代码如下:#include "stdafx.h"#define EXPORT __declspec(dllexport)extern "C" EXPORT void __stdcall Showdialg(char* pText);3、在动态链接库源⽂件中定义showdialog函数,代码如下:void _stdcall Showdialg(char* pText){MessageBox(NULL,pText,"提⽰⼀",0);}注:此步编译后,即可⽣成dll与lib⽂件,因为_stdcall是⼀种⽐较流⾏的函数调⽤约定,(或者可以不⽤_stdcall),如果使⽤的时候,为了防⽌发⽣函数命令改编的情况,可以定义⼀个.def⽂件,其中加⼊EXPORTS节,设置导出函数名,如下所⽰:LIBRARY "login_dll"EXPORTSShowdialg = Showdialg4、创建⼀个基于对话框的⼯程。
5、定义⼀个函数指针类型,其定义与动态链接库的函数原型相同,代码如下:typedef void (__stdcall * funShowInfo)(char* pchData);6、处理按键单击事件,加载动态链接库,代码如下:void Cuse_login_dllDlg::OnBnClickedOk(){HMODULE hMod = LoadLibrary("login_dll.dll");if (hMod != NULL){funShowInfo ShowInfo;ShowInfo = (funShowInfo)GetProcAddress(hMod,"Showdialg");if (ShowInfo)ShowInfo("传⼊参数成功且调⽤正常");}FreeLibrary(hMod);}其中,第5步与第6步是通过LoadLibrary函数动态加载链接库的⽅法,下⾯介绍⼀下静态加载链接库的⽅法:1、加载链接库的头⽂件,将动态链接库头⽂件拷贝到当前⼯程中,并在当前⼯程头⽂件进⾏声明。
制作CC++动态链接库(dll)若⼲注意事项⼀、C\C++ 运⾏时库编译选项简单说明问题:我的dll别⼈没法⽤运⾏时库是个很复杂的东西,作为开发过程中dll制作需要了解的⼀部分,这⾥主要简单介绍⼀下如何选择编译选项。
在我们的开发过程中时常会遇到这样的问题:1. 我的VS版本⽐较⾼(⽐如:VS2012),我想制作⼀个dll,封装了⼏个函数给别⼈⽤。
2. 打包后发现我的dll引⽤了msvcr110.dll或者msvcr110d.dll,这个dll别⼈电脑可能没有。
3. 于是别⼈使⽤时出现了诸如:“⽆法在DLL“XXXX.dll”中找到名为“XXXX()”的⼊⼝点”等问题。
最终结果就是,反复检查发现都没有错,⽤⼯具查看也发现函数确实已经导出了,但是别⼈就没法⽤。
这⾥可能就需要对编译选项进⾏修改了。
解释:如何避免上述问题在VS中打开:项⽬属性——>配置属性——>C/C++——>代码⽣成——>运⾏时。
其中可以看到多个选项,如下图所⽰:在微软的msdn中对CRT库进⾏了简单解释:下⾯是我黏贴的表格:选项说明/MD使应⽤程序使⽤运⾏时库的多线程并特定于 DLL 的版本。
定义_MT和_DLL,并使编译器将库名MSVCRT.lib 放⼊ .obj ⽂件中。
⽤此选项编译的应⽤程序静态链接到 MSVCRT.lib。
该库提供允许链接器解析外部引⽤的代码层。
实际⼯作代码包含在 MSVCR80.DLL 中,该库必须在运⾏时对于与 MSVCRT.lib 链接的应⽤程序可⽤。
当在定义了_STATIC_CPPLIB (/D_STATIC_CPPLIB) 的情况下使⽤/MD时,它将导致应⽤程序与静态多线程标准 C++ 库 (libcpmt.lib) ⽽⾮动态版本 (msvcprt.lib) 链接,同时仍通过 msvcrt.lib 动态链接到主 CRT。
/MDd定义_DEBUG、_MT和_DLL,并使应⽤程序使⽤运⾏时库的调试多线程并特定于 DLL 的版本。
操作系统实验一_动态链接库的建立与调用动态链接库(Dynamic Link Library,简称DLL),是一种可执行文件格式,可以包含一些可被其他程序共享和调用的代码、数据和资源。
与静态链接库相比,动态链接库在系统运行时被加载,可以实现动态更新和共享代码的功能。
在操作系统实验一中,我们将学习如何建立和调用动态链接库。
动态链接库的建立通常包括以下步骤:1.编写库文件的源代码:首先,需要编写动态链接库所包含的代码。
这些代码可以是函数、类、变量等程序模块的实现。
在编写代码时,需要注意代码的可重用性和可扩展性,以便其他程序可以调用和使用这些代码。
2.编译源代码生成库文件:将源代码编译成目标文件,并链接生成动态链接库文件。
在编译和链接过程中,需要根据编译器和操作系统的要求设置编译选项和链接选项,例如指定动态链接库的输出格式和名称等。
3.导出函数和符号:在编写代码时,需要使用适当的方式声明和定义函数、类、变量等实体,以便其他程序可以调用和使用它们。
在编译和链接过程中,需要使用一些特殊的关键字或指令来指定导出的函数和符号。
4.生成库文件:使用编译器和链接器将目标文件生成动态链接库文件,并进行必要的优化和处理。
生成的库文件通常包含一些元数据信息,例如导出函数和符号的位置和名称等。
动态链接库的调用通常包括以下步骤:1.导入库文件的头文件:在调用动态链接库的程序中,需要包含动态链接库的头文件。
该头文件包含了库文件中导出函数和符号的声明和定义。
2.加载动态链接库:在程序启动时,需要使用操作系统提供的加载动态链接库的函数来加载动态链接库文件。
加载动态链接库时,需要提供动态链接库的文件路径或其他标识符。
3.获取导出函数的地址:在加载动态链接库后,可以使用操作系统提供的函数来查询和获取动态链接库中导出函数和符号的地址。
获取导出函数的地址后,可以通过函数指针来调用动态链接库中的函数。
4.调用动态链接库函数:通过获取到的函数指针,可以直接调用动态链接库中的函数。
在Linux下,我们可以使用GCC编译器来编译动态链接库(.so文件)。
以下是一个简单的示例,演示了如何创建一个动态链接库。
假设我们有一个简单的C程序,它定义了一个函数add,该函数接受两个整数并返回它们的和。
c// add.c#include<stdio.h>int add(int a, int b) {return a + b;}接下来,我们需要编写一个头文件add.h,以供其他程序使用。
c// add.h#ifndef ADD_H#define ADD_Hint add(int a, int b);#endif// ADD_H现在,我们编写一个动态链接库程序libadd.c。
该程序包含了上面定义的头文件和函数。
c// libadd.c#include"add.h"int add(int a, int b) {return a + b;}编译动态链接库的步骤如下:1.使用gcc编译器将C源文件编译为共享对象文件。
使用-shared选项指定输出为共享对象文件。
例如:2.shellgcc -shared -o libadd.so add.c libadd.c这将生成一个名为libadd.so的共享对象文件。
2. 将生成的共享对象文件复制到适当的位置。
例如,您可以将文件复制到系统的库目录中:shellsudo cp libadd.so /usr/local/lib/这将将共享对象文件复制到/usr/local/lib/目录下,这样其他程序就可以找到并链接它。
请注意,可能需要使用超级用户权限来执行此操作。
在Linux Eclipse中,使用动态链接库的方法如下:
1. 创建动态链接库:
* 创建一个新的C++项目,选择Shared Library -> Empty Project,输入工程名,点击finish,完成工程的创建。
* 在h文件中,将要用到这个库的函数声明放到一个.h文件中,如果需要在其他工程中使用这个库,只需要将这个.h文件加载到工程中。
* 编写代码,封装动态链接库。
在Linux下,只需要直接把要封的函数的声明放到一个.h文件中。
* 生成动态链接库,编译代码,成功后在Debug目录下会生成.so 文件。
2. 使用动态链接库:
* 创建一个新的C++项目,选择Executable -> Empty Project,工程名为libxxx。
* 编写所需代码,并将相应的.h文件放到工程目录下并加载到工程中。
* 加入动态链接库libxxx.so。
右键工程Properties -> C/C++
Build -> Settings,在右边找到库的名称xxx变为a,库的路径就写这个库所在的路径。
* 修改环境变量。
具体操作步骤可能因不同的操作系统或编译器而有所不同,建议查阅相关文档或教程以获取更详细的信息。
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文件。