https://docs.microsoft.com/zh-cn/troubleshoot/windows-client/deployment/dynamic-link-library
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位?)。
新建一个控制台程序来调用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文件夹下
2021.9.26更新,后来我又试了一次发现不用改这里的路径,只用拷过去就行了。不是很明白第一次是怎么错的。
然后再点“本地Windows调试”就能运行了。(这时候倒不告诉我不是32位不行了)
visual studio 生成的dll也可以被Java调用,但是要多设置一些东西
属性→VC++目录→包含目录
加入jdk的安装的两个地址
Java和C++是可以共用一套导出函数的,但是主要Java和c++的变量类型存在一定差异,可以参考下边这个链接
https://www.cnblogs.com/liangqihui/p/13729819.html
解决方法:右键工程名–>属性–>C/C+±->预处理器–>预处理器定义,编辑右边输入框加入:
_CRT_SECURE_NO_WARNINGS
问题原因: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。修改配置后,程序恢复正常。
在预处理器定义这儿多加上一行(虽然我截图的时候是已经加完了的)
加上这句
_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