yabo88登陆 VS2019使用C / C ++动态链接库并对其进行调用

日期:2021-02-20 15:07:45 浏览量: 155

将以下函数添加到CPP_DLL.cpp文件,并在函数声明之前添加extern“ C” _declspec(dllexport)关键字。

// C 的方式声明导出
extern "C"
{
	_declspec(dllexport) int subFunc(int a, int b);
	int subFunc(int a, int b)
	{
		return a + b;
	}
}

示例屏幕截图:

c++ 动态链接库

然后单击“生成解决方案”,您可以在调试目录或项目目录的发布目录中生成动态链接库的相关文件(取决于您生成调试版本还是发布版本)。第三方调用时的密钥文件是项目目录中的.lib文件和.dll文件以及.h标头文件。

方法2:导出模块定义文件

在项目中定义CPP_DLL.def文件,这是一个模块导出文件

c++ 动态链接库

在CPP_DLL.cpp文件中添加以下功能

LIBRARY
EXPORTS
  mulFunc
  divFunc

示例屏幕截图:

c++ 动态链接库

如果它是VS平台泛亚体育 ,则必须在连接器中添加.def文件

c++ 动态链接库

然后单击“生成解决方案”,您可以在调试目录或项目目录的发行目录中生成动态链接库的相关文件(取决于您生成的是调试版本还是发行版本)。第三方调用时的密钥文件是项目目录中的.lib文件和.dll文件以及.h标头文件。

c++ 动态链接库

对应的DLL和lib文件

c++ 动态链接库

2.调用以前开发的动态链接库

1.创建一个新的C / C ++项目(测试)

c++ 动态链接库

c++ 动态链接库

2.将第三方库的.h文件,.lib文件和.dll文件复制到项目中

.dll文件是一个动态链接库,需要加载该链接才能运行该程序。在VS中进行调试时,可以通过project-> properties-> debugging-> environment列添加.dll文件的路径以成功调试,但是要独立运行.exe程序必须将.dll文件放在同一目录中

动态素材库_程序员的自我修养:链接,装载和库pdf_c++ 动态链接库

因此,建议将.dll文件直接放入调试目录或发布目录中。只要可以通过路径找到.h头文件和.lib库文件,就可以随意放置它们。为了方便管理泛亚体育 ,建议创建一个文件夹并将其放置在项目目录中。

3.调用项目中的第三方库

有三种方法可以调用第三方库。

([1)在代码前直接添加引号

由于直接引用CPPDLL.h头文件c++ 动态链接库,因此必须将动态链接库的函数声明放在头文件中。

修改CPP_DLL的.h文件和cpp文件现金牛牛 ,将函数声明放在.h中凤凰体育App ,并将函数定义放入cpp文件中。

CPP_DLL.h

// C++ 的方式声明导出
_declspec(dllexport) int addFunc(int a, int b);
// C 的方式声明导出
extern "C"
{
	_declspec(dllexport) int subFunc(int a, int b);
}
int mulFunc(int a, int b);
double divFunc(double a, double b);

CPP_DLL.cpp

int addFunc(int a, int b)
{
    return a + b;
}
int subFunc(int a, int b)
{
	return a - b;
}
// def 文件形式
int mulFunc(int a, int b)
{
	return a * b;
}
double divFunc(double a, double b)
{
	return a / b;
}

重新生成DLL文件,然后将DLL,lib和.h文件复制到相应的目录中

C ++测试代码:

c++ 动态链接库

#include 
#include "./CPP_DLL.h"   //通过相对路径或绝对路径添加头文件
#pragma comment (lib,"./CPPDLL.lib")  // 添加 lib 文件
int main()
{
    std::cout << "Hello World!\n";
    std::cout << addFunc(1, 2) << std::endl;
    std::cout << subFunc(3, 4) << std::endl;
    std::cout << mulFunc(5, 6) << std::endl;
    std::cout << divFunc(7, 8) << std::endl;
}

运行结果的屏幕截图:

c++ 动态链接库

([2)在解决方案管理面板中添加头文件和资源文件

添加一个现有的头文件,在文件夹中找到第三方库的头文件(CPP_DLL.h),并将其添加到新创建的项目中。

添加现有资源文件,在文件夹中找到第三方库文件(CPPDLL.lib),并将其添加到新创建的项目中。

c++ 动态链接库

([3)在项目属性->设置中添加头文件和库文件

c++ 动态链接库

c++ 动态链接库

在函数中的第三方库中调用函数

#include 
int main()
{
    std::cout << "Hello World!\n";
    std::cout << addFunc(1, 2) << std::endl;
    std::cout << subFunc(3, 4) << std::endl;
    std::cout << mulFunc(5, 6) << std::endl;
    std::cout << divFunc(7, 8) << std::endl;
}

4.直接在代码中加载动态库dll文件

此方法不需要包含.h文件,也不需要添加lib库和lib库路径c++ 动态链接库

由于C ++声明的动态链接库的名称更改将更改已编译函数的名称,因此需要使用该工具查看已编译动态链接库的函数名称。

对于外部“ C”声明和def文件声明,编译后的函数名称不会更改,可以直接使用。

VS2019附带了工具dumpbin.exe,用于查看与已编译的动态链接库相对应的函数名称。

c++ 动态链接库

打开命令行yabo2020 ,然后输入命令dumpbin -exports CPPDLL.dll

c++ 动态链接库

结果截图:

c++ 动态链接库

所以addFunc不能直接使用,只能使用nameMangling之后的名称,这里addFunc的编译名称是addFunc @@ YAHHH @ Z

示例程序代码:

#include 
#include 
// 加、减、乘 都是 int 类型
typedef int(*lpFunc)(int a, int b); //后边为参数,前面为返回值
// 除法 是 double 类型
typedef double(*lpFuncD)(double a, double b); //后边为参数,前面为返回值
int main()
{
    std::cout << "Hello World!\n";
	HMODULE hModule;
	hModule = LoadLibrary(L"CPPDLL.dll"); //调用DLL	
	lpFunc lpfunc = NULL;
	// GetProcAddress为获取该函数的地址 
	// "?addFunc@@YAHHH@Z" 这个就是 C++  Name Mangling后的 addFunc 的函数名
	lpfunc = (lpFunc)GetProcAddress(hModule, "?addFunc@@YAHHH@Z");
    std::cout << lpfunc(1, 2) << std::endl;
	/* 使用 C extern 和 def 文件定义的动态链接库,函数名不会发生变化 */
	lpfunc = (lpFunc)GetProcAddress(hModule, "subFunc");
	std::cout << lpfunc(3, 4) << std::endl;
	lpfunc = (lpFunc)GetProcAddress(hModule, "mulFunc");
	std::cout << lpfunc(5, 6) << std::endl;
	lpFuncD lpfuncd = NULL;
	lpfuncd = (lpFuncD)GetProcAddress(hModule, "divFunc");
	std::cout << lpfuncd(7, 8) << std::endl;
	
	//释放
	FreeLibrary(hModule);	
}

运行结果:

c++ 动态链接库

方法5:使用lib文件和dll文件

c++ 动态链接库

示例代码:

#include 
// addFunc 是使用 C++ 方式声明的,
_declspec(dllimport) int addFunc(int a, int b);
//subFunc 是 使用 extern "C" 声明的
extern "C" _declspec(dllimport) int subFunc(int a, int b);
// mulFunc 和 divFunc 是 使用 def 声明的
_declspec(dllimport) int mulFunc(int a, int b);
_declspec(dllimport) double divFunc(double a, double b);
int main()
{
    std::cout << "Hello World!\n";
    std::cout << addFunc(1, 2) << std::endl;
    std::cout << subFunc(3, 4) << std::endl;
    std::cout << mulFunc(5, 6) << std::endl;
    std::cout << divFunc(7, 8) << std::endl;
    return 0;
}

运行结果:

c++ 动态链接库

您还可以使用#pragma comment(lib,“ ./ CPPDLL.lib”)//添加lib文件,与第一种方法结合使用

无需手动设置和添加lib文件。

#include 
#pragma comment (lib,"./CPPDLL.lib")
// addFunc 是使用 C++ 方式声明的,
_declspec(dllimport) int addFunc(int a, int b);  // 声明 addFunc 函数
//subFunc 是 使用 extern "C" 声明的
extern "C" _declspec(dllimport) int subFunc(int a, int b);  // 声明 subFunc 函数
// mulFunc 和 divFunc 是 使用 def 声明的
_declspec(dllimport) int mulFunc(int a, int b);             // 声明 mulFunc 函数
_declspec(dllimport) double divFunc(double a, double b);    // 声明 divFunc 函数
int main()
{
    std::cout << "Hello World!\n";
    std::cout << addFunc(1, 2) << std::endl;
    std::cout << subFunc(3, 4) << std::endl;
    std::cout << mulFunc(5, 6) << std::endl;
    std::cout << divFunc(7, 8) << std::endl;
    return 0;
}