java调C接口_java通过jni调用C程序接口

打算写一个FbSetApp去操作framebuffer的设备文件,以便能够去设置FB的一些参数。

新建两个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起始位置和大小的参数。

FbSetControl.java:

package org.trident.fbset;

public class FbSetControl {

static {

System.loadLibrary("fbset");

}

public native int Init();

public native int SetPosition();

}

然后在FbSetApp下,执行:

javac -d bin src\org\trident\app\FbParams.java

javac -d bin src\org\trident\app\FbSetControl.java

然后转到FbSetApp\bin\classes下

javah -d ../../jni org.trident.app.FbSetControl

这样就会在FbSetApp\jni目录下生成org_trident_app_FbSetControl.h:

如果报文件无法访问和找不到类,那么多半是环境变量设置有问题:

java_home:C:\Program Files\Java\jdk1.7.0_01(java安装好后的路径),

Path变量中添加 %java_home%/bin,

classpath:.;%java_home%/lib

加入我们自己要用到的结构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创建一个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部分参数传递的方法,在此有必要说明一下:

jfieldID fid;

jclass tprm = (*env)->GetObjectClass(env, tparam);

作用是拿到传递的env中我们添加的tparam结构的指针

fid = (*env)->GetFieldID(env, tprm, "pos_x", "I");

作用是拿到tparam结构中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);

然后再增加一个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文件了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值