java上位机开发(c库调用)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】所有的动态语言,包括在java在内,一般都会提供一个调用c库的方法。java语言的出现是在上个世纪90年代,而c/c++出现的时间要更早一点,大约提前了20多年,所以在这过程当中积累了很多的资源可以调用。此外,由于c/c++可以直接控制硬件,可以直接加速算法的执行,所以作为上位机开发的同学来说,掌
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
所有的动态语言,包括在java在内,一般都会提供一个调用c库的方法。java语言的出现是在上个世纪90年代,而c/c++出现的时间要更早一点,大约提前了20多年,所以在这过程当中积累了很多的资源可以调用。此外,由于c/c++可以直接控制硬件,可以直接加速算法的执行,所以作为上位机开发的同学来说,掌握好c库调用也是很有必要的。
c库调用的方法很多,比较常用的就是jni。jvm作为java虚拟机,调用class字节码,这个大家都了解。那字节码如果需要调用c库,一般会在java代码中有一个显示调用的过程,关键字是native。注意native是函数的名字,不是动态库的名字,动态库的名字一般用System.LoadLibrary来完成,也就是上述图中蓝色的部分。对于简单的动态库,只需要在浅绿色中实现即可。而对于opencv、pcl点云、ffmpeg、jpeg、png这样成熟的动态库来说,浅绿色的部分就是一个翻译的过程,库本身还是原来黄色的部分。这就是绿色和黄色两个模块的区别。下面举例说明,
1、假设有一个java文件,需要调用一个显示HelloWorld的c方法,
public class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("HelloWorldImpl");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
HelloWorld helloWorld = new HelloWorld();
helloWorld.displayHelloWorld();
}
}
代码中需要调用的dll库是HelloWorldImpl,对应的函数是displayHelloWorld。
2、编译HelloWorld.java,直接调用javac命令即可
3、生成HelloWorld.h文件,直接调用javah命令即可
4、准备编译dll,可以通过CMake来完成,准备CMakeLists.txt和HelloWorldImpl.cpp文件
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
#MESSAGE( STATUS "this var key = ${CMAKE_CURRENT_SOURCE_DIR}.")
SET (LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/HelloWorldImpl.cpp)
ADD_LIBRARY (HelloWorldImpl SHARED ${LIB_SRC})
INSTALL(TARGETS HelloWorldImpl RUNTIME DESTINATION ../../../Debug)
SET_TARGET_PROPERTIES(HelloWorldImpl PROPERTIES LINKER_LANGUAGE CPP)
HelloWorldImpl.cpp代码如下所示,
#include "HelloWorld.h"
#include <stdio.h>
#include <jni.h>
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject)
{
printf("Hello World, ABC!\n");
return;
}
5、通过CMakeLists.txt构建solution文件,编译solution
6、编译dll,应该会出现找不到jni.h的情形,注意添加编译头文件的位置
添加的两个头文件目录是,
C:\Program Files (x86)\Java\jdk1.8.0_91\include
C:\Program Files (x86)\Java\jdk1.8.0_91\include\win32
7、重新编译dll,不出意外应该可以生成dll文件
8、将HelloWorldImpl.dll拷贝到顶层,执行java程序,查看是否可以运行通过
9、其他
不管是java,还是js、go、python、perl、rust这些语言,都会有调用c库的方法。在实际开发中可以借助于这些方法,不需要重新造轮子就可以实现原来语言没有的功能,而不是在网上不停地去找代码、找方案。
注:
现在也可以用jna直接访问dll库,比如这个范例,
package org.example;
import com.sun.jna.*;
import com.sun.jna.win32.StdCallLibrary;
/**
* Hello world!
*
*/
interface JNAApiInterface extends Library {
@SuppressWarnings( "deprecation")
JNAApiInterface INSTANCE = (JNAApiInterface) Native.loadLibrary(
Platform.isWindows() ? "msvcrt" : "c", JNAApiInterface.class);
void printf( String format, Object... args );
int sprintf( byte[] buffer, String format, Object... args );
int scanf( String format, Object... args );
}
public class App {
public static void main( String args[] ) {
System.out.println("Hello");
JNAApiInterface jnaLib = JNAApiInterface.INSTANCE;
jnaLib.printf("Hello World\n");
// this is dangerous as you don't control how long user input is
// but for learning it's fine, you will crash with longer names
byte[] testName = new byte[100];
jnaLib.printf("Please Enter Your Name: \n");
jnaLib.scanf("%s", testName);
jnaLib.printf("\nYour name is %s", Native.toString(testName));
}
}
更多推荐
所有评论(0)