01.Jni开发流程_java调用C/C++-阿里云开发者社区

开发者社区> 黑夜路口> 正文

01.Jni开发流程_java调用C/C++

简介: (创建于2017/11/18) JNI(Java Native Interface) Java调用C/C++,C/C++调用Java的一套API 1.编写native方法 public class JniUtils { public stati...
+关注继续查看

(创建于2017/11/18)

JNI(Java Native Interface)
Java调用C/C++,C/C++调用Java的一套API

1.编写native方法

public class JniUtils {
    public static native String getStringFromC();
    public native String getStringFromC2();
}

2.javah命令,生成.h头文件

cd 进入到src目录下,使用命令生成头文件 javah 包名+类型(如 com.renzhenming.utils.JniUtils)

3.复制.h头文件到CPP工程中

右键->添加现有项->将头文件添加到vs中的头文件目录中,不要直接复制,直接复制无效

4.复制jni.h和jni_md.h文件到CPP工程中

发现在我们生成的头文件中有对jni.h 的导入,jni.h中又有对jni_md.h的导入,所以我们直接去jdk目录下搜索道这两个头文件,引入到工程中,同样是添加现有项
注意include的时候,<>与“”的灵活使用,假设生成的头文件是这样的(有时候Javah命令生成的头文件中没有方法名,只有一些预编译的东西,不知何故)

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_renzhenming_bsdiff_JniUtils */

#ifndef _Included_com_renzhenming_bsdiff_JniUtils
#define _Included_com_renzhenming_bsdiff_JniUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_renzhenming_bsdiff_JniUtils
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_renzhenming_bsdiff_JniUtils_getStringFromC
  (JNIEnv *, jclass);

/*
 * Class:     com_renzhenming_bsdiff_JniUtils
 * Method:    getStringFromC2
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_renzhenming_bsdiff_JniUtils_getStringFromC2
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

5.实现.h头文件中声明的函数

假设如上边一样,我们生成了头文件,那么我们需要在自己的c文件中定义实现这两个方法

#include "com_renzhenming_bsdiff_JniUtils.h"    //引入头文件

JNIEXPORT jstring JNICALL Java_com_renzhenming_bsdiff_JniUtils_getStringFromC
(JNIEnv *env, jclass jcls) {
    return (*env)->NewStringUTF(env, "aaaaaaa");  //得到字符串
}

JNIEXPORT jstring JNICALL Java_com_renzhenming_bsdiff_JniUtils_getStringFromC2
(JNIEnv *env, jobject jobj) {
    return (*env)->NewStringUTF(env, "bbbbbb");//得到字符串
}

6.visual studio生成dll文件


img_34b78a9c2dfcbc0c22dc5d0d7b62af4b.png
37761343.png

如上点击debug出现下拉框,选择配置管理器,将我们的活动解决方案设置为x64


img_89df1598f30f5d29b5043162942d7af0.png
37833718.png

右键项目名->属性,设置常规下的项目默认值下的配置类型选择动态库(.dll),然后
img_d2c374a5b964ba33d9190922e4c06657.png
37905203.png

点击生成,选择生成解决方案,这时候我们的dll动态库就生成在指定目录中了


img_8963a5a8598867b94a5f29a6519bdea4.png
37963765.png

7.vs生成dll动态库的时候容易出现的问题和解决方法
1.使用了过时的函数

严重性 代码  说明  项目  文件  行   禁止显示状态
错误  C4996   'open': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _open. See online help for details. ndk_update  c:\users\renzhenming\documents\visual studio 2015\projects\ndk_update\ndk_update\bsdiff.cpp 263 
    
解决办法:给所在的类添加宏定义
define _CRT_NONSTDC_NO_DEPRECATE
或者给整个项目添加右键项目名->属性->配置属性->c/c++->命令行,在其他选项中添加 -D _CRT_NONSTDC_NO_DEPRECATE,确定即可,这样会给整个项目设置这个配置,不再需要在每个类中分别添加了
2.使用了不安全的函数

严重性 代码  说明  项目  文件  行   禁止显示状态
错误  C4996   'open': This function or variable may be unsafe. Consider using _sopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ndk_update  c:\users\renzhenming\documents\visual studio 2015\projects\ndk_update\ndk_update\bsdiff.cpp 263 
    
解决办法:同上的方式添加宏定义,_CRT_SECURE_NO_WARNINGS
3.安全性检查相关的问题

bsdiff是外国程序员写的,可能使用的工具不是vs,而vs对代码安全性检查比较严格,所以导致这个问题
在linux系统下不会报这个错误

严重性 代码  说明  项目  文件  行   禁止显示状态
错误  C4703   使用了可能未初始化的本地指针变量“old”   ndk_update  c:\users\renzhenming\documents\visual studio 2015\projects\ndk_update\ndk_update\bsdiff.cpp 266 
错误  C4703   使用了可能未初始化的本地指针变量“V” ndk_update  c:\users\renzhenming\documents\visual studio 2015\projects\ndk_update\ndk_update\bsdiff.cpp 273 
错误  C4703   使用了可能未初始化的本地指针变量“_new”  ndk_update  c:\users\renzhenming\documents\visual studio 2015\projects\ndk_update\ndk_update\bsdiff.cpp 295 
    
解决办法:右键项目名->属性->配置属性->c/c++->常规->SDL检查选择否
4.重复引用的问题

这个错误的原因是因为项目中既添加了bsdiff.cpp也添加了bspatch.cpp文件,导致出现定义的重复问题
也就是二者不可同时存在,移除一个

严重性 代码  说明  项目  文件  行   禁止显示状态
错误  LNK2005 "void __cdecl err(int,char const *)" (?err@@YAXHPEBD@Z) 已经在 bsdiff.obj 中定义  ndk_update  c:\Users\renzhenming\Documents\Visual Studio 2015\Projects\ndk_update\ndk_update\bspatch.obj    1   
错误  LNK2005 "void __cdecl errx(int,char const *)" (?errx@@YAXHPEBD@Z) 已经在 bsdiff.obj 中定义    ndk_update  c:\Users\renzhenming\Documents\Visual Studio 2015\Projects\ndk_update\ndk_update\bspatch.obj    1   
错误  LNK1169 找到一个或多个多重定义的符号  ndk_update  c:\Users\renzhenming\Documents\Visual Studio 2015\Projects\ndk_update\x64\Debug\ndk_update.exe  1   
    
解决办法:针对这个项目的编译,不要让两者同时存在

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
小记基于xstate实现携程金服业务流程动态化
小记基于xstate实现携程金服业务流程动态化
7 0
Spring Boot 基础教程:配置详解
本文主要对 Spring Boot 项目中的配置文件进行了简单的介绍,并学习如何自定义属性并配置多环境项目,最后则是对比了当前主流的两种方式不同格式配置文件 yml 和 properties 的异同。
5 0
【在家实践】 ECS 初体验
第一次体验云服务器,感觉十分奇妙。
8 0
冬季实战营学习报告 第一期:从零到一上手玩转云服务器
这一期训练营从1月17号开始,为期5天。主要内容是了解学习阿里云的云服务(ECS) 因为提前加入了阿里云社区活动群,管理员每天都会提醒我们登录账号打卡学习,这里感谢管理员对我们的监督😊😊。
13 0
宝塔面板远程登录连接FTP空间详细教程
原文更精彩:https://www.yundashi168.com/276.html 原文更精彩:https://www.yundashi168.com/276.html
6 0
ecs服务器使用体验
分享一下使用ecs服务器的体验和经历
8 0
基于阿里云服务器安装Docker完整图文教程
基于阿里云服务器安装Docker完整图文教程
7 0
阿里云初体验
web开发打包部署到linux服务器
16 0
使用APICloud AVM框架开发预约应用
前段时间跟朋友一起搞了一个预约的项目,前端用的APICloud的AVM框架做的,后端用的php开发的,用的tp5框架,没几天就搞出来了。简单跟大家分享一下开发中的一些功能点的实现吧。也欢迎大家一起探讨。
5 0
+关注
黑夜路口
安卓高级工程师,目前任职于Wifi万能钥匙
152
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载