DLL有两种加载方式:
静态加载和动态加载。
静态加载的步骤:
注:当dll本身并不独立,还要依赖第三方的库而不是windows下的库时
(1) 包含DLL中导出的头文件。
(2) 采用#pragma comment(lib,"..\\debug\\libTest.lib")导入动态库生成的*.lib头文件,要在项目中进行设置(VS studio)。
(3) 将动态库生成的*.dll文件放到EXE或DLL的同一目录下。
动态加载的步骤:
Another.dll有一个int Add(int x,int y) 函数。
则完整的调用过程如下:
typedef int (* FunPtr)(int,int); //定义函数指针
FunPtr funPtr; Handle handle =LoadLibrary("Another.dll");
funPtr =(FunPtr)GetProcAddress(handle ,"Add");
funPtr(2,3); // 2+3;
FreeLibrary(handle); // 释放载入的动态库
本次需求:
利用eclipse,clion,mingw-32在windows 10上为java1.8 32位写一个jni,实现简单的加法及打印字符串
重点:对c++,c的编译即将cpp文件编译成.o文件,修改生成的cpp文件,最后再编译成dll
参考文档:https://juejin.im/entry/5865d619ac502e006d5ee1e1
参考以上文档生成header文件等,我们这里生成的.h文件如图一,.cpp为自己手动新建的,如图二
图一
图二
解决__int64不能识别的问题:
解决编译jni_util.c文件undefined reference to canonicalize:
编译过程:
1.转换为.o文件:原因是g++不能同时编译c,c++文件,因为java某些.c文件 g++不能编译成.o文件,原因是一些写法导致,只能用gcc才行,都转换成.o文件就可以最后直接用g++ 链接.o文件
(1)将jni_uti.c用gcc -c jni_util.c编译成.o文件
(2)将HelloWorld.cpp文件编译成HelloWorld.o文件
2.链接为dll文件
g++ -L"F:\HelloWorld\lib" -Wl,--add-stdcall-alias -shared -o libHelloWorld.dll HelloWorld.o jni_util.o -ljvm
F:\HelloWorld\lib的内容为:
最后就是使用dll了
libHelloWorld.dll中要引用的dll,jvm默认会去java.library.path中找,如下:
删除jre/bin下的相关dll后,stardard vm设置的为jdk,jre时结果都一样
涉及到的项目:java:https://github.com/doodoocoder/HelloWorldJava
c++: https://github.com/doodoocoder/HelloWorldCplus