Visual Studio 2019 DLL生成使用 x64 C++ Java Windows

1 关于dll的简单介绍

https://docs.microsoft.com/zh-cn/troubleshoot/windows-client/deployment/dynamic-link-library

2 Visual Studio 2019 DLL生成

Visual Studio 2019默认的配置是x86,我去查了一下是32位的,而我们要是64位的,要选那个x64。(但是我不明白为什么32位的他们就不能用了,不是应该向下兼容的么)

补充:后来估计应该是为了匹配64位的jdk。

参考了这个教程,但是一步一步跟着它的走实际上我是会报错的,查了一下是dll没读到,教程里是直接把dll复制到该项目的Debug文件夹下的。
https://blog.csdn.net/Giser_D/article/details/89677441

为了防止原链接挂掉,相同步骤我也简单复述一下。

打开Visual Studio 2019→创建新项目→创建动态链接库(dll)→下一步→命名为DemoDll

在头文件中定义宏,宏的作用的是允许该函数能够被外部访问,并直接调用。

pch.h中写入代码

// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
 
#ifndef PCH_H
#define PCH_H
 
// 添加要在此处预编译的标头
#include "framework.h"
 
#endif //PCH_H
 
//定义宏
#ifdef IMPORT_DLL
#else
#define IMPORT_DLL extern "C" _declspec(dllimport) //指的是允许将其给外部调用
#endif
 
IMPORT_DLL int add(int a, int b);
IMPORT_DLL int minus(int a, int b);
IMPORT_DLL int multiply(int a, int b);
IMPORT_DLL double divide(int a, int b);

dllmain.cpp文件写入代码

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"

int add(int a, int b)
{
	return a + b;
}

int minus(int a, int b)
{
	return a - b;
}

int multiply(int a, int b)
{
	return a * b;
}

double divide(int a, int b)
{
	double m = (double)a / b;
	return m;
}

注意框里这俩的内容
在这里插入图片描述
然后原教程说是点击生成,但是我看别的也有说点击本地Windows调试器的,我点的是这个调试器,它会成功但是弹窗告诉你不是有效的32位文件无法打开(我很不能理解,为什么都这个年代了主流还是32位?)。
Visual Studio 2019 DLL生成使用 x64 C++ Java Windows_第1张图片

3 C++ DLL调用

新建一个控制台程序来调用dll。也调成Debug和x64。

(其实也不一定非要是Debug,Release也可,但是都要遵循一条原则,就是dll和控制台程序的Debug或Release必须保持一致)

Debug和Release的区别
http://c.biancheng.net/view/4124.html

Debug 版本
   Debug 是“调试”的意思,Debug 版本就是为调试而生的,
编译器在生成 Debug 版本的程序时会加入调试辅助信息,并且很少会进行优化,程序还是“原汁原味”的。
   你没听错,不是任何一个程序都可以调试的,程序中必须包含额外的辅助信息才能调试,否则调试器也无从下手。

Release 版本
   Release 是“发行”的意思,Release 版本就是最终交给用户的程序,编译器会使尽浑身解数对它进行优化,
以提高执行效率,虽然最终的运行结果仍然是我们期望的,但底层的执行流程可能已经改变了。
   编译器还会尽量降低 Release 版本的体积,把没用的数据一律剔除,包括调试信息。
   最终,Release 版本是一个小巧精悍、非常纯粹、为用户而生的程序。

.cpp中写入代码

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include 
using namespace std;
int main()
{
	HINSTANCE hDllInst;
	hDllInst = LoadLibrary(L"DemoDll.dll"); //调用DLL
	typedef int(*PLUSFUNC)(int a, int b); //后边为参数,前面为返回值
	PLUSFUNC plus_str = (PLUSFUNC)GetProcAddress(hDllInst, "add"); //GetProcAddress为获取该函数的地址
	std::cout << plus_str(1, 2);
}

你可以生成一下或者直接在该项目的文件夹下新建Debug文件夹。然后把DemoDll.dll拷贝进去
(如果是Release的话,这里应该是在x64/Release下)

这时候调试会报一个“0xC0000005: 执行位置 0x0000000000000000 时发生访问冲突。”,的错误。一般会指向GetProcAddress那行或者它的下一行,反正都是这行出的问题,网上搜了一下比较多是说的空指针错误,我加了一堆打印后发现是LoadLibrary那里就压根没读进去,hDllInst==NULL。

解决方案资源管理器那里,本项目名称右键单击,属性,配置属性,调试,工作目录,改成该项目相应的Debug文件夹下
Visual Studio 2019 DLL生成使用 x64 C++ Java Windows_第2张图片

 2021.9.26更新,后来我又试了一次发现不用改这里的路径,只用拷过去就行了。不是很明白第一次是怎么错的。

然后再点“本地Windows调试”就能运行了。(这时候倒不告诉我不是32位不行了)

4 DLL Java调用

visual studio 生成的dll也可以被Java调用,但是要多设置一些东西

属性→VC++目录→包含目录
Visual Studio 2019 DLL生成使用 x64 C++ Java Windows_第3张图片
加入jdk的安装的两个地址
Visual Studio 2019 DLL生成使用 x64 C++ Java Windows_第4张图片
Java和C++是可以共用一套导出函数的,但是主要Java和c++的变量类型存在一定差异,可以参考下边这个链接
https://www.cnblogs.com/liangqihui/p/13729819.html

5 sprintf等函数报错不安全

解决方法:右键工程名–>属性–>C/C+±->预处理器–>预处理器定义,编辑右边输入框加入:

_CRT_SECURE_NO_WARNINGS

6 for_each_n 不是std的成员

问题原因:c++版本不是17
https://www.cnblogs.com/justaname/p/12006155.html
解决方法:右击项目->属性->C/C+±>语言->C++ 语言标准 。 当设置为默认值(应该即为 IOS2014 C++ 14 标准)时,_MSVC_LANG值为 201402L,当其值设置为:IOS2017 C++ 17 标准时,_MSVC_LANG值为 201703L。修改配置后,程序恢复正常。

7 没有正确结尾

解决方法:改成不使用预编译头
Visual Studio 2019 DLL生成使用 x64 C++ Java Windows_第5张图片

8 ‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. OpenSSLaes

Visual Studio 2019 DLL生成使用 x64 C++ Java Windows_第6张图片
在预处理器定义这儿多加上一行(虽然我截图的时候是已经加完了的)
Visual Studio 2019 DLL生成使用 x64 C++ Java Windows_第7张图片
加上这句

_CRT_SECURE_NO_WARNINGS


Visual Studio其他相关链接整理

打开别人的MFC项目后,法打开源文件”afxwin.h”
https://blog.csdn.net/sky130054/article/details/109535632

VS2010+命令行编程、命令行参数
https://blog.csdn.net/liqian_blog/article/details/80111027

“const wchar_t *” 类型的实参与 “LPCSTR” 类型的形参不兼容的原因和解决方法
https://blog.csdn.net/cxm2643199642/article/details/105624148

你可能感兴趣的:(C/C++,基础,c++,visual,studio,windows,dll,java)