IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++:项目中的dll的构建和dll的导入函数并执行(VS2015) -> 正文阅读

[C++知识库]C/C++:项目中的dll的构建和dll的导入函数并执行(VS2015)

当前环境:vs2015

1. 声明

当前内容主要为记录在VS2015中编写dll和在项目中导入dll并执行函数的操作(从hotspot中发现dll可以通过LoadLibrary加载并执行)

加载和执行dll

  1. 隐式加载dll (#pragma comment(lib,“xx.lib”)方式加载)
  2. 显示加载dll(LoadLibrary方式加载)

2. 编写程序并生成dll

1. 创建控制台项目并指定为dll程序
在这里插入图片描述

2.编写头文件test.h

#pragma once
extern "C" _declspec(dllexport) 
void printStar(int rowNum,int cellNum);

这里需要注意的是:如果不使用extern "C" _declspec(dllexport) 表现所有的函数都是使用C++样式的,反之就是使用C样式的,C样式的不会修改函数名称,C++样式的会修改函数名称

这个对于后面的使用LoadLibrary方式加载dll和函数调用有非常重要的区别(LoadLibrary调用函数时按照函数名称得到函数指针的,如果得不到就会返回126)

这里为了解决LoadLibrary中的函数调用所以这里直接就保持不变(使用C导出样式)

3.编写函数实现

#include "stdafx.h"
#include<stdlib.h>
#include <stdio.h>
#include "test.h"

void printStar(int rowNum, int cellNum) {
	for (int i = 0; i < rowNum; i++)
	{
		for (int j = 0; j < cellNum; j++)
		{
			printf("*");
		}
		printf("\n");
	}
}

开始生成dll和lib
在这里插入图片描述

3. 在另外一个项目中调用该dll库

首先将上面的test.h头文件拷贝到另外一个项目中,随后将TestDll.dll和Test.lib拷贝到项目的目录下面(必要时可以将test.h也拷贝进去)
在这里插入图片描述

1. 使用隐式调用方式

#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
#include "test.h"
#pragma comment(lib,"TestDll.lib") 
int main()
{
	printStar(5, 5);
	getchar();
    return 0;
}

2. 使用显示调用方式

#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
#include "test.h"
int main()
{
	void (*printStar)(int, int)=NULL;
	HINSTANCE handle;
	LPCWSTR libPath = TEXT("TestDll.dll");//;
	printf("before load dll\n");
	if ((handle = LoadLibrary(libPath))==0) {
		printf("dll load failed !\n");
		DWORD errorMsg = GetLastError();
		std::cout << errorMsg << endl;
		return 0;
	}
	LPCSTR functionName = "printStar"; // 非C样式的函数导出会导致这个函数名称改变
	printStar = (void (*)(int, int))GetProcAddress(handle, functionName);
	if (printStar==0) {
		printf("get function failed !\n");
		DWORD errorMsg= GetLastError();
		std::cout << errorMsg << endl;
		return 0;
	}
	
	printStar(5,5);
	// 释放加载的lib
	FreeLibrary(handle);
	getchar();
    return 0;
}

执行结果都是一样的!
在这里插入图片描述

4. 查看C和C++导出函数

这里本人采用DLL Export Viewer查看dll

1. C样式的
在这里插入图片描述
2.C++样式的
在这里插入图片描述
这里可以发现C++样式的看不到函数名称,C样式的却可以看到

5. 总结

  1. 使用隐式导入的时候一般都是可以调用的,只要头文件正确,但是对于显示导入的时候就会出现C++和C的函数名称不一致的问题,导致显示导入出现找不到函数名称(默认vs采用C++的样式)
  2. 可以采用DLL Export Viewer观察生成的函数名称避免在导入中出现的各种问题
  3. 对于Linux中手动导入dll库的没有查看但是hotspot源码中已经有了加载dll的例子了
    在这里插入图片描述
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:02:42  更:2022-07-17 16:05:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:21:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码