java调C接口_java通过jni调用C程序接口
打算寫一個(gè)FbSetApp去操作framebuffer的設(shè)備文件,以便能夠去設(shè)置FB的一些參數(shù)。
新建兩個(gè)class
FbParams.java:
package org.trident.fbset;
public class FbParams {
int pos_x;
int pos_y;
int size_x;//Width
int size_y;//Height
}
用于傳遞FB起始位置和大小的參數(shù)。
FbSetControl.java:
package org.trident.fbset;
public class FbSetControl {
static {
System.loadLibrary("fbset");
}
public native int Init();
public native int SetPosition();
}
然后在FbSetApp下,執(zhí)行:
javac -d bin src\org\trident\app\FbParams.java
javac -d bin src\org\trident\app\FbSetControl.java
然后轉(zhuǎn)到FbSetApp\bin\classes下
javah -d ../../jni org.trident.app.FbSetControl
這樣就會在FbSetApp\jni目錄下生成org_trident_app_FbSetControl.h:
如果報(bào)文件無法訪問和找不到類,那么多半是環(huán)境變量設(shè)置有問題:
java_home:C:\Program Files\Java\jdk1.7.0_01(java安裝好后的路徑),
Path變量中添加 %java_home%/bin,
classpath:.;%java_home%/lib
加入我們自己要用到的結(jié)構(gòu)cnxtfb_position
org_trident_app_FbSetControl.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class org_trident_fbset_FbSetControl */
#ifndef _Included_org_trident_fbset_FbSetControl
#define _Included_org_trident_fbset_FbSetControl
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:???? org_trident_fbset_FbSetControl
* Method:??? Init
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_trident_fbset_FbSetControl_Init
(JNIEnv *, jobject);
/*
* Class:???? org_trident_fbset_FbSetControl
* Method:??? GetResolution
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_trident_fbset_FbSetControl_GetResolution
(JNIEnv *, jobject, jobject tparam);
/*
* Class:???? org_trident_fbset_FbSetControl
* Method:??? SetPosition
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_trident_fbset_FbSetControl_SetPosition
(JNIEnv *, jobject, jobject tparam);
typedef struct _cnxtfb_position{
int nPosX;
int nPosY;
int nSizeX;
int nSizeY;
}cnxtfb_position;
typedef struct _cnxtfb_resolution{
int uWidth;
int uHeight;
}cnxtfb_resolution;
#ifdef __cplusplus
}
#endif
#endif
在FbSetApp/jni創(chuàng)建一個(gè)C文件,org_trident_fbset_FbSetControl.c:
#include
#include
#include
#include
#include
#include
#define? DEVICE_NAME? "/dev/fb0"? //device point
#define FBIO_SET_POSITION????? 0x4637
#define FBIO_GETFBRESOLUTION????? 0x4626
#define? OMX_HAL_IOCTL_SET_SCREEN_POS_HW_CURSOR 0x12
static cnxtfb_position fb_pos;
static cnxtfb_resolution fb_res;
//#define DBG 0
#define? LOG_TAG??? "fbset"
#define? printf(...)? __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:???? FbSetControl
* Method:??? Init
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_trident_fbset_FbSetControl_Init
(JNIEnv * env, jobject? obj)
{
fb_pos.nPosX = 0;
fb_pos.nPosY = 0;
fb_pos.nSizeX = 0;
fb_pos.nSizeX = 0;
printf("%d %d,%d %d",fb_pos.nPosX,fb_pos.nPosY,fb_pos.nSizeX,fb_pos.nSizeY);
}
/*
* Class:???? FbSetControl
* Method:??? GetResolution
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_trident_fbset_FbSetControl_GetResolution
(JNIEnv * env, jobject? obj, jobject tparam)
{
jfieldID fid;
jclass tprm = (*env)->GetObjectClass(env, tparam);
static int fbfd = -1;
if (fbfd < 0)
{
if ( ( fbfd = open( "/dev/fb0", O_RDWR ) ) < 0 )
{
printf(stderr, "open %s error!\n",DEVICE_NAME);
//return -1;
}
if (ioctl(fbfd, FBIO_GETFBRESOLUTION, &fb_res)) {
printf(stderr, "error FBIO_SET_POSITION screeninfo!\n");
//return -1;
}
fid = (*env)->GetFieldID(env, tprm, "width", "I");
(* env)->SetIntField(env,tparam, fid, fb_res.uWidth);
printf("uWidth is %d",fb_res.uWidth);
fid = (*env)->GetFieldID(env, tprm, "height", "I");
(* env)->SetIntField(env,tparam, fid, fb_res.uHeight);
printf("uHeight is %d",fb_res.uWidth);
close(fbfd);
fbfd=-1;
}
}
JNIEXPORT jint JNICALL Java_org_trident_fbset_FbSetControl_SetPosition
(JNIEnv * env, jobject? obj, jobject tparam)
{
jfieldID fid;
jclass tprm = (*env)->GetObjectClass(env, tparam);
static int fbfd = -1;
static int cursorfd = -1;
fid = (*env)->GetFieldID(env, tprm, "pos_x", "I");
fb_pos.nPosX = (*env)->GetIntField(env, tparam, fid);
printf("nPosX is %d",fb_pos.nPosX);
fid = (*env)->GetFieldID(env, tprm, "pos_y", "I");
fb_pos.nPosY = (*env)->GetIntField(env, tparam, fid);
printf("nPosY is %d",fb_pos.nPosY);
fid = (*env)->GetFieldID(env, tprm, "size_x", "I");
fb_pos.nSizeX = (*env)->GetIntField(env, tparam, fid);
printf("nSizeX is %d",fb_pos.nSizeX);
fid = (*env)->GetFieldID(env, tprm, "size_y", "I");
fb_pos.nSizeY = (*env)->GetIntField(env, tparam, fid);
printf("%d %d,%d %d",fb_pos.nPosX,fb_pos.nPosY,fb_pos.nSizeX,fb_pos.nSizeY);
#ifdef DBG
//printf("%d %d,%d %d",fb_pos.nPosX,fb_pos.nPosY,fb_pos.nSizeX,fb_pos.nSizeY);
#else
if (fbfd < 0)
{
if ( ( fbfd = open( "/dev/fb0", O_RDWR ) ) < 0 )
{
printf(stderr, "open %s error!\n",DEVICE_NAME);
//return -1;
}
if (ioctl(fbfd, FBIO_SET_POSITION, &fb_pos)) {
printf(stderr, "error FBIO_SET_POSITION screeninfo!\n");
//return -1;
}
close(fbfd);
fbfd=-1;
}
if (cursorfd < 0)
{
if ((cursorfd = open("/dev/HW_CURSOR", O_RDWR))<0)
{
printf("Failed to open HD cursor node warnerye.\n");
//return ;
}
if(ioctl(cursorfd, OMX_HAL_IOCTL_SET_SCREEN_POS_HW_CURSOR, &fb_pos) < 0)
{
printf("change Cursor FB POSITION failed: %s\n", strerror(errno));
close(cursorfd);
cursorfd = -1;
//return;
}
close(cursorfd);
cursorfd=-1;
}
#endif
}
#ifdef __cplusplus
}
#endif
對于jni部分參數(shù)傳遞的方法,在此有必要說明一下:
jfieldID fid;
jclass tprm = (*env)->GetObjectClass(env, tparam);
作用是拿到傳遞的env中我們添加的tparam結(jié)構(gòu)的指針
fid = (*env)->GetFieldID(env, tprm, "pos_x", "I");
作用是拿到tparam結(jié)構(gòu)中pos_x的ID,"I"表示是int,如果我們要傳遞字符串變量,比如IP地址,可以這樣寫:
const char *ip;
jfieldID fid;
jstring jstr;
jclass tprm = (*env)->GetObjectClass(env, tparam);
fid = (*env)->GetFieldID(env, tparam, "ipadd", "Ljava/lang/String;");
jstr = (*env)->GetObjectField(env,tparam, fid);
ip = (*env)->GetStringUTFChars(env, jstr, NULL);
//strcpy(param.pszSrcAddr,ip);
(*env)->ReleaseStringUTFChars(env,jstr,ip);
printf("ip is %s",params.pszSrcAddr);
然后再增加一個(gè)Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE??? := fbset
LOCAL_SRC_FILES := org_trident_fbset_FbSetControl.c
LOCAL_C_INCLUDES := inc
LOCAL_LDLIBS??? := -lm -llog -ljnigraphics
LOCAL_LDLIBS??? += -LD:/Android/workspace/fbset/jni/lib
include $(BUILD_SHARED_LIBRARY)
然后就可以使用ndk-build編譯生成so,要做這一步,你需要安裝NDK,安裝步驟你可以參照:
安裝完成以后你就可以在cygwin下面編譯jni部分的代碼生成so文件了。
總結(jié)
以上是生活随笔為你收集整理的java调C接口_java通过jni调用C程序接口的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java gz文件解压_java – 批
- 下一篇: java 5 新特性 for_java5