使用python开发宏_python 宏定义

引用来自“anjingyuws”的答案

引用来自“fcsong000833”的答案

测试了一上午发现原来不是C调用java接口出了问题,而是在java调用C接口时出问题,如下C接口

int Java_com_example_jni_jni_jniRead( JNIEnv* env, jobject obj, jbyteArray data, jint datalen){  jbyte *s8data;

s8data = (*env)->GetByteArrayElements(env,data,0);

//以下两句存在不存在都一个样

(*env)->DeleteLocalRef(env, s8data);

s8data = NULL;

return 0;

}

就这么个简单接口调用N(大概900多次)就崩溃,屏蔽GetByteArrayElements

正常,请教是什么原因呢,该如何修改??

GetByteArrayElements之后是需要ReleaseByteArrayElements的

至于主贴中的问题,个人猜想还是因为那个init中NewObject导致局部引用表溢出崩溃的首先保证这个方法真的只调用一次(可以通过在init中输出LOG查看,或者通过引用计数之类的方法),而且对于需要在其他函数中调用的情况,还应该保证mTestProvider为GlobalRef,也就是修改NewObject为NewGlobalRef,但切记在不使用的时候DeleteGlobalRef

这段代码看起来问题还是蛮多的:

"SendJ = (*jniEnv)->GetMethodID(jniEnv, TestProvider, "javaSend","([BI)I");    if(NULL == obdSendJ)return 5;"

这个SendJ和下面的obdSendJ有啥关系?

"if(nativeMethod_firstcall == 1)CtoJavaInit();"

这里面的nativeMethod_firstcall什么时候赋值的?都怎么操作了?

我针对你的需求把你的代码修改了一下,你看看能不能符合要求吧:

static jobject g_testProvider = NULL; static jmethodID g_sendJ = NULL; static int g_inited = 0; int CtoJavaInit(JNIEnv * env) {     int res = 0;     jmethodID ctrId = NULL;     jclass cls = (*env)->FindClass(env, "com/example/jni/C2jni");     if (NULL == cls)     {         res = 2;         goto end_func;     }     ctrId = (*env)->GetMethodID(env, cls, "", "()V");     if(NULL == ctrId)     {         res = 3;         goto end_func;     }     g_testProvider = (*env)->NewGlobalRef(env, cls, ctrId);     if(NULL == g_testProvider)     {         res = 4;         goto end_func;     }     // 其实javaSend的参数没必要添加长度,Java中数组本身是知道自身长度的     g_sendJ = (*env)->GetMethodID(env, cls, "javaSend","([BI)I");     if(NULL == g_sendJ)     {         res = 5;         goto end_func;     } end_func:     (*env)->DeleteLocalRef(env, cls);     return res; } int cSend(JNIEnv * env, char * data, int datalen) {     int len, intresult;     jbyteArray bytes = NULL;     if(NULL == g_testProvider || NULL == g_sendJ)     {         return 0;     }     if(NULL == data || datalen > 128)     {         return 0;     }     bytes = (*env)->NewByteArray(env, datalen);     if(NULL == bytes)     {         return 0;     }     (*env)->SetByteArrayRegion(env, bytes, 0, datalen, (const jbyte *)data);     (*env)->CallIntMethod(env, g_testProvider, g_sendJ, bytes, datalen);     (*env)->DeleteLocalRef(env, bytes);     return datalen; } JNIEXPORT void JNICALL Java_nativeMethod (JNIEnv * env, jclass thiz) {     // 这里比较好的做法是将init和cleanup分别在Java端应用开始时和结束时调用,比如onCreate和onDestroy中调用     char *sendtest = "test...";     if (g_inited == 0)     {         CtoJavaInit(env);         g_inited = 1;     }     cSend(env, sendtest, strlen(sendtest));     CtoJavaCleanup(env); } void CtoJavaCleanup (JNIEnv * env) {     if (g_testProvider != NULL)     {         (*env)->DeleteGlobalRef(env, g_testProvider);         g_testProvider = NULL;     } }

不好意思,上面的代码有些错误: JNIEXPORT void JNICALL Java_nativeMethod (JNIEnv * env, jclass thiz)

{

// 这里比较好的做法是将init和cleanup分别在Java端应用开始时和结束时调用,比如onCreate和onDestroy中调用

char *sendtest = "test...";

if (g_inited == 0)

{

CtoJavaInit(env);

g_inited = 1;

}

cSend(env, sendtest, strlen(sendtest));

// 找个合适的地方调用

// 尽量还是把初始化和资源清理单独调用的好……

// CtoJavaCleanup(env);

}

######回复

@fcsong000833 : 还有个问题忘了说,JNIEnv是针对线程有效的,所以尽量不要通过变量保存其指针,最好每次都使用JNI方法传过来的参数,如果需要在一些已经定义好的回调接口中使用,应该用JavaVM的AttachCurrentThread来获取当前线程的JNIEnv######非常感谢,虽然现在用其他方式暂时规避了这个问题,但这个代码还是很有价值。谢谢######

问题没解决啊 , 继续请求帮忙 .... ######建议去iteye的高级语言虚拟机群问问######

引用来自“南湖船老大”的答案

建议去iteye的高级语言虚拟机群问问

还是喜欢这里,高手啊 ....

######何必呢,在JE里面马上就有回答的。######

引用来自“fcsong000833”的答案

引用来自“南湖船老大”的答案

建议去iteye的高级语言虚拟机群问问

还是喜欢这里,高手啊 ....

论会员技术水平,iteye远高于osc,毕竟那里底子厚

######什么错误?######

引用来自“南湖船老大”的答案

引用来自“fcsong000833”的答案

引用来自“南湖船老大”的答案

建议去iteye的高级语言虚拟机群问问

还是喜欢这里,高手啊 ....

论会员技术水平,iteye远高于osc,毕竟那里底子厚

注册后还得闭嘴一天   哎 。。。

######

引用来自“michaely”的答案

什么错误?

A: java应用

B: java通讯接口

C: JNI中的C接口

C调用B

A循环调用C,N次(200次左右)软件崩溃, 我也崩溃了 ,找不到头绪。。。

######

宏哥来给你终极解决方案吧

需要和C集成的地方, 用python.

python可以暴露web借口给 java。 其实lua也可以。

jvm是一个平台, 设计到和操作系统直接沟通的地方, 用jni就是自找麻烦。

“ decision over convention, convention over configuration"

这就是为什么要坚持两个凡是的原因 ######回复

@郭煜 : android中实现http协议太简单了######用C简单实现一个http协议也是可以的,这么做过,不依赖任何库,代码量也不大,但是是单线程阻塞模型的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值