前言
同事在debian9下用javacpp做了jni, 给java工程用。
让我试试在windows下如何编译和使用javacpp.
开始在网上看零散的资料,不好使啊,写的都很糙。
找到官方的帮助页面(https://github.com/bytedeco/javacpp/wiki/Examples),一步一步的照官方说的做,也不行(编译或运行报错).
头痛…
后来自己折腾了好久,才发现,是官方demo的写法和编译的细节上没说清楚。
记录一下,搞定后的官方demo修改版,是啥样子。和原版区别很细微。
实验
编译过,运行成功的javacpp工程: src_test_javacpp_official_demo_1.zip
编译环境
win10
java 1.8.0_161 64bits
javacpp 1.5 (https://github.com/bytedeco/javacpp/releases/tag/1.5)
vs2017专业版15.9.11
Source Insight 4.0
适用于 VS 2017 的 x64 本机工具命令提示(这个很重要)
javacpp实现
// @file \javacpp_for_win\test_case\test_javacpp_official_demo_1\Abc.hpp
// @ref https://github.com/bytedeco/javacpp/wiki/Examples
class Abc {
public:
void testMethod(int a) {
printf(">> testMethod(%d)\r\n", a);
}
};
java调用javacpp的实现
// @file \javacpp_for_win\test_case\test_javacpp_official_demo_1\Abc.java
// @ref https://github.com/bytedeco/javacpp/wiki/Examples
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include = "Abc.hpp" /*link = "Abc"*/)
// "link" tells javacpp which original library should be linked (if not specified, "Abc" will be used)
public class Abc extends Pointer {
static {
// error
// Loader.loadLibrary("jniAbc"); // Specify name of our wrapper library
// ok
Loader.load(); // This method can be used if JNI wrapper named as class, i.e. "jniAbc"
}
public Abc() {
allocate(); // To be able to create Abc instances from Java we should wrap allocator
}
public native void allocate(); // Define allocator
public native void testMethod(int a); // Method we want to use
public static void main(String[] args) {
System.out.println("hello\n");
Abc abc = new Abc();
abc.testMethod(123);
}
}
编译和运行过程
因为开始按照官方手册,怎么都编译或运行不过。
我整了几个.cmd, 将中间的命令记录下来,也节省时间。
第一关键的编译步骤是:必须打开vs2017的64位命令行环境,否则后续编译或运行不过。
运行.cmd的顺序如下:
必须先打开vs2017命令行环境 "适用于 VS 2017 的 x64 本机工具命令提示"
然后在vs2017命令行环境中运行 *.cmd
clear_prj.cmd
build_java_prj.cmd
build_jni_prj.cmd
run_java_prj.cmd
clear_prj.cmd
clear_prj.cmd
@echo off
echo --------------------------------------------------------------------------------
echo clear project ...
del /Q .\Abc.class
del /Q .\jniAbc.cpp
del /Q .\jniAbc.obj
del /Q .\jnijavacpp.cpp
del /Q .\jnijavacpp.obj
del /Q .\jniAbc.exp
del /Q .\jniAbc.lib
del /Q .\jniAbc.dll
del /Q .\Abc.dll
del /Q .\Abc.exp
del /Q .\Abc.lib
del /Q .\Abc.obj
echo clear project over
echo .
echo .
echo .
echo .
echo .
echo .
echo --------------------------------------------------------------------------------
cmd
build_java_prj.cmd
@echo off
echo --------------------------------------------------------------------------------
echo build java project ...
del /Q Abc.class
echo Abc.class was delete
javac -cp javacpp.jar Abc.java
echo build java project over
echo .
echo .
echo .
echo .
echo .
echo .
echo --------------------------------------------------------------------------------
cmd
build_jni_prj.cmd
@echo off
echo --------------------------------------------------------------------------------
echo build jni project ...
java -jar javacpp.jar -d . -o jniAbc -Xcompiler -L. Abc
echo build jni project over
echo .
echo .
echo .
echo .
echo .
echo .
echo --------------------------------------------------------------------------------
cmd
run_java_prj.cmd
@echo off
echo --------------------------------------------------------------------------------
echo run java project ...
set JAVA_HOME
rem JAVA_HOME=C:\Program Files\Java\jdk1.8.0_161
set CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
set CLASSPATH
rem CLASSPATH=.;C:\Program Files\Java\jdk1.8.0_161\lib\dt.jar;C:\Program Files\Java\jdk1.8.0_161\lib\tools.jar
java -cp javacpp.jar;. Abc
echo run java project over
echo .
echo .
echo .
echo .
echo .
echo .
echo --------------------------------------------------------------------------------
cmd
编译和运行效果
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.11
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional>cd /d D:\my_test\test_javacpp_official_demo_1
D:\my_test\test_javacpp_official_demo_1>dir
驱动器 D 中的卷没有标签。
卷的序列号是 640B-BD29
D:\my_test\test_javacpp_official_demo_1 的目录
2019/06/06 15:17 <DIR> .
2019/06/06 15:17 <DIR> ..
2019/06/06 13:06 239 Abc.hpp
2019/06/06 14:27 1,047 Abc.java
2019/06/06 13:18 388 build_java_prj.cmd
2019/06/06 14:30 360 build_jni_prj.cmd
2019/06/06 13:49 544 clear_prj.cmd
2019/04/08 21:24 398,612 javacpp.jar
2019/06/06 15:11 283 readme.txt
2019/06/06 14:25 597 run_java_prj.cmd
8 个文件 402,070 字节
2 个目录 118,334,656,512 可用字节
D:\my_test\test_javacpp_official_demo_1>clear_prj.cmd
--------------------------------------------------------------------------------
clear project ...
找不到 D:\my_test\test_javacpp_official_demo_1\Abc.class
找不到 D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp
找不到 D:\my_test\test_javacpp_official_demo_1\jniAbc.obj
找不到 D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp
找不到 D:\my_test\test_javacpp_official_demo_1\jnijavacpp.obj
找不到 D:\my_test\test_javacpp_official_demo_1\jniAbc.exp
找不到 D:\my_test\test_javacpp_official_demo_1\jniAbc.lib
找不到 D:\my_test\test_javacpp_official_demo_1\jniAbc.dll
找不到 D:\my_test\test_javacpp_official_demo_1\Abc.dll
找不到 D:\my_test\test_javacpp_official_demo_1\Abc.exp
找不到 D:\my_test\test_javacpp_official_demo_1\Abc.lib
找不到 D:\my_test\test_javacpp_official_demo_1\Abc.obj
clear project over
.
.
.
.
.
.
--------------------------------------------------------------------------------
Microsoft Windows [版本 10.0.17763.529]
(c) 2018 Microsoft Corporation。保留所有权利。
D:\my_test\test_javacpp_official_demo_1>build_java_prj.cmd
--------------------------------------------------------------------------------
build java project ...
找不到 D:\my_test\test_javacpp_official_demo_1\Abc.class
Abc.class was delete
build java project over
.
.
.
.
.
.
--------------------------------------------------------------------------------
Microsoft Windows [版本 10.0.17763.529]
(c) 2018 Microsoft Corporation。保留所有权利。
D:\my_test\test_javacpp_official_demo_1>build_jni_prj.cmd
--------------------------------------------------------------------------------
build jni project ...
Generating D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp
Generating D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp
Compiling D:\my_test\test_javacpp_official_demo_1\jniAbc.dll
cl "/IC:\Program Files\Java\jdk1.8.0_161\include" "/IC:\Program Files\Java\jdk1.8.0_161\include\win32" D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp /Oi /O2 /EHsc /Gy /GL /MD /LD -L. /W3 /link /OUT:jniAbc.dll psapi.lib
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.16.27030.1 版
版权所有(C) Microsoft Corporation。保留所有权利。
cl: 命令行 warning D9002 :忽略未知选项“-L.”
jniAbc.cpp
D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp(250): warning C4267: “参数”: 从“size_t”转换到“jsize”,可能丢失 数据
D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp(251): warning C4267: “参数”: 从“size_t”转换到“jsize”,可能丢失 数据
D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp(260): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(133): note: 参见“strcpy”的声明
D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp(262): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(338): note: 参见“strncpy”的声明
jnijavacpp.cpp
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(565): warning C4267: “参数”: 从“size_t”转换到“jsize”,可能 丢失数据
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(566): warning C4267: “参数”: 从“size_t”转换到“jsize”,可能 丢失数据
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(607): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(133): note: 参见“strcpy”的声明
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(609): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(338): note: 参见“strncpy”的声明
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(913): warning C4244: “参数”: 从“jlong”转换到“jint”,可能丢 失数据
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(914): warning C4244: “参数”: 从“jlong”转换到“jint”,可能丢 失数据
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(1314): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(338): note: 参见“strncpy”的声明
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(1386): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(133): note: 参见“strcpy”的声明
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(1427): warning C4996: 'strerror': This function or variable may be unsafe. Consider using strerror_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(182): note: 参见“strerror”的声明
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(1445): warning C4996: 'strncat': This function or variable may be unsafe. Consider using strncat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(266): note: 参见“strncat”的声明
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(1479): warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(440): note: 参见“strtok”的声明
D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp(1535): warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\string.h(90): note: 参见“strcat”的声明
Microsoft (R) Incremental Linker Version 14.16.27030.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:jniAbc.dll
/ltcg
/dll
/implib:jniAbc.lib
/OUT:jniAbc.dll
psapi.lib
jniAbc.obj
jnijavacpp.obj
正在创建库 jniAbc.lib 和对象 jniAbc.exp
正在生成代码
已完成代码的生成
Deleting D:\my_test\test_javacpp_official_demo_1\jniAbc.cpp
Deleting D:\my_test\test_javacpp_official_demo_1\jnijavacpp.cpp
build jni project over
.
.
.
.
.
.
--------------------------------------------------------------------------------
Microsoft Windows [版本 10.0.17763.529]
(c) 2018 Microsoft Corporation。保留所有权利。
D:\my_test\test_javacpp_official_demo_1>run_java_prj.cmd
--------------------------------------------------------------------------------
run java project ...
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_161
CLASSPATH=.;C:\Program Files\Java\jdk1.8.0_161\lib\dt.jar;C:\Program Files\Java\jdk1.8.0_161\lib\tools.jar
hello
>> testMethod(123)
run java project over
.
.
.
.
.
.
--------------------------------------------------------------------------------
Microsoft Windows [版本 10.0.17763.529]
(c) 2018 Microsoft Corporation。保留所有权利。
D:\my_test\test_javacpp_official_demo_1>