如何在Java js for循环中调用函数C函数

Android 中Java 和C/C++的相互调用方法
在一些应用的开发中,需要通过JNI和Android NDK工具实现JAVA和C/C++之间的相互调用。
Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI是本地接口,它使得在Java(VM)内部运行的Java代码能够与用其它编程语言(如C、C++和汇编语言)编写的应用程序和库进行交互操作。
由于Android的应用层的类都是以Java写的,这些Java类编译为Dex型式的Bytecode之后,必须靠Dalvik虚拟机(VM: Virtual Machine)来执行。在执行Java类的过程中,如果Java类需要与C沟通时,VM就会去载入C组件,然后让Java的函数顺利地调用到C组件的函数。此时,VM扮演着桥梁的角色,让Java与C组件能通过标准的JNI介面而相互沟通。
在实际应用中这两者之间的调用关系可以归纳为以下四种方式:
1. 在应用的JAVA代码中调用NDK中C/C++实现的函数。
2. 在NDK开发中的C/C++代码调用应用中JAVA类的静态函数。
3. 在NDK开发中的C/C++代码调用应用中JAVA类当前传入NDK中的实例的函数。
4. 在NDK开发中的C/C++代码调用应用中JAVA类新建实例的函数。
下面我们就怎样在Eclipse中实现JNI编码和四种调用方式加以阐述。
一、在Eclipse中建立一个包含JNI开发的工程。
在这里我们不直接导入NDK中的hello-jni来说明JNI的使用方法。而是新建立一个工程,来说明怎样建立一个包含JNI的工程。
第一步:建立一个Andriod工程JniDemo,在该工程的根目录下建立一个叫jni的目录,在jni目录下建立一个叫Android.mk的文件,(当然你也可以从其他地方,比如ndk样例代码hello-jni中将里面的Android.mk复制过来修改)。Android.mk里面的内容如下所示
LOCAL_PATH :=$(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE:= demo-jni
LOCAL_SRC_FILES := demo-jni.c
include$(BUILD_SHARED_LIBRARY)
关于这几句话的含义,在这里不再赘述。网上搜下,就可以很明白。
然后在jni目录下生成demo-jni.c文件。实现的接口的内容。
现在选中工程中的jni目录,点击鼠标右键,选Refresh,jni目录中的文件就显示在工程的jni目录下了。
第二步:设置jni的编译环境。选中工程中的根目录JniDemo,点击鼠标右键,选Properties。弹出对话框,选中列表中的Builders。如图一所示:
图一:JniDemo特性设置对话框
点击对话框右端的new按钮,弹出&Choose configuration type&对话框,如图二,选择Program,点击对话框下面的OK按钮。
图二:选择配置类型
现在我们打开了&Edit Configuration&对话框,在Name对应的文本框中输入名字JniBuilder(当然也可是你喜欢的其他名字).在Main选项下,在Location中输入cygwin中bash.exe的绝对路径。我这里是c:\cygwin\bin\bash.exe(c:\cygwin\为我的系统中cygwin的安装目录,这里要根据你的电脑中cygwin的安装目录来确定),在Working Directory中输入c:\cygwin\bin\.在Arguments中输入--login -c &cd /cygdrive/d/study/JniDemo && /cygdrive/d/android-ndk-r6b/ndk-build&。这里/cygdrive/d/study/JniDemo为工程根目录,/cygdrive/d/android-ndk-r6b为NDK的安装目录。这两个目录参数根据你的工程目录和ndk的安装目录而定。注意的是驱动器要采用cygwin的方式。(比如:Windows系统下的D:对应/cygdrive/d,其余类推)。设置结果如图三所示,然后点击OK按钮即可。
图三:编辑JNI配置参数
二、演示四种调用方式
演示界面如图四所示,四个按钮分别测试四种调用方式。
图四:演示界面图
分别点击按钮Test1, Test2, Tes3, Test四的测试结果如图五、六、七、八所示。
图五:点击Test1的测试结果
图六:点击Test2的测试结果
图七:点击Test3的测试结果
图八:点击Test4的测试结果
Test1演示在应用中调用NDK中C/C++实现的函数。JAVA代码和C代码分别为:
JAVA代码:
[java]view plaincopy
Buttonbtn01=(Button)findViewById(R.id.Button01);
btn01.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
TextViewtv=(TextView)findViewById(R.id.tv01);
tv.setText(stringFromJNI());
showMessage(JniDemoActivity.this,&JNItest1&,stringFromJNI());
view plaincopy
JstringJava_study_jnidemo_JniDemoActivity_stringFromJNI(JNIEnv*env,jobjectthiz)
return(*env)-&NewStringUTF(env,&JniDemo,HellofromJNI!&);
lTest2静态调用。JAVA代码和C代码分别为:
JAVA代码:
[java]view plaincopy
//测试C/C++中对JAVA函数的静态回调
Buttonbtn02=(Button)findViewById(R.id.Button02);
btn02.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
intret=jniStaticShowMessage(JniDemoActivity.this,&JNItest2&,&teststaticcallbackMessage&);
TextViewtv=(TextView)findViewById(R.id.tv01);
if(ret==0)
tv.setText(&testJNIstaticcallbacksuccessed&);
tv.setText(&testJNIstaticcallbackfialed&);
view plaincopy
JintJava_study_jnidemo_JniDemoActivity_jniStaticShowMessage(JNIEnv*env, view plaincopy
jobjectthiz,jobjectctx,jstringstrTitle,jstringstrMessage)
jclasscls=(*env)-&FindClass(env,&study/jnidemo/JniDemoActivity&);
//jclasscls=(*env)-&GetObjectClass(env,thiz);
if(cls!=NULL)
jmethodIDid=(*env)-&GetStaticMethodID(env,cls,&staticShowMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(id!=NULL)
return(*env)-&CallStaticIntMethod(env,cls,id,ctx,strTitle,strMessage);
lTest3当前实例调用:JAVA代码和C代码分别为:
JAVA代码:
[java]view plaincopy
Buttonbtn03=(Button)findViewById(R.id.Button03);
btn03.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
strTest=&[messagehaschangednow]&;
intret=jniShowMessage(JniDemoActivity.this,&JNItest3&,&testcallbackincurrentinstance&);
TextViewtv=(TextView)findViewById(R.id.tv01);
if(ret==0)
tv.setText(&testJNIcallbacksuccessed&);
tv.setText(&testJNIcallbackfialed&);
view plaincopy
JintJava_study_jnidemo_JniDemoActivity_jniShowMessage(JNIEnv*env,jobjectthiz,
jobjectctx,jstringstrTitle,jstringstrMessage)
jclasscls=(*env)-&GetObjectClass(env,thiz);
if(cls!=NULL)
jmethodIDstrTest_id=(*env)-&GetMethodID(env,cls,&getTestString&,&()Ljava/lang/S&);
if(strTest_id!=NULL)
str=(*env)-&CallObjectMethod(env,thiz,strTest_id);
jmethodIDshowMessage_id=(*env)-&GetMethodID(env,cls,&showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id!=NULL)
return(*env)-&CallIntMethod(env,thiz,showMessage_id,ctx,
strTitle,combine_jstring(env,strMessage,str));
lTest4新建实例调用:JAVA代码和C代码分别为:
JAVA代码:
[java]view plaincopy
Buttonbtn04=(Button)findViewById(R.id.Button04);
btn04.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
strTest=&[messagehaschangednow]&;
intret=jniInstanceShowMessage(JniDemoActivity.this,
JNItest4&,&testcallbackinnewinstance&);
TextViewtv=(TextView)findViewById(R.id.tv01);
if(ret==0)
tv.setText(&testJNInewinstancesuccessed&);
tv.setText(&testJNInewinstancefialed&);
view plaincopy
jintJava_study_jnidemo_JniDemoActivity_jniInstanceShowMessage(JNIEnv*env,jobjectthiz,
jobjectctx,jstringstrTitle,jstringstrMessage)
jclasscls=(*env)-&FindClass(env,&study/jnidemo/JniDemoActivity&);
if(cls!=NULL)
//getinstance
jmethodIDconstuctor_id=(*env)-&GetMethodID(env,cls,&&,&()V&);
if(constuctor_id!=NULL)
jobjectobj=(*env)-&NewObject(env,cls,constuctor_id);
if(obj!=NULL)
jmethodIDstrTest_id=(*env)-&GetMethodID(env,cls,&getTestString&,&()Ljava/lang/S&);
if(strTest_id!=NULL)
str=(*env)-&CallObjectMethod(env,obj,strTest_id);
jmethodIDshowMessage_id=(*env)-&GetMethodID(env,cls,&showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id!=NULL)
return(*env)-&CallIntMethod(env,obj,showMessage_id,ctx,strTitle,combine_jstring(env,strMessage,str));
Test1和Test2都是常规的调用,在这里不做解释了。现在我们看看Test3和Test4的区别,在Test3中,strTest=& [message has changed now]&在相应的代码中都做了赋值。但是在Test4中并没有改变,还是初始值。这是因为Test创建了一个新实例,和应用的JAVA代码中所赋值的实例并不是同一个。因此才出现了不同的结果。
附完整的JAVA和C代码
JAVAD代码:JniDemoActivity.java
[java]view plaincopy
packagestudy.
importandroid.app.A
importandroid.app.AlertD
importandroid.os.B
importandroid.widget.B
importandroid.view.V
importandroid.widget.TextV
importandroid.content.C
importandroid.content.DialogI
publicclassJniDemoActivityextendsActivity{
publicStringstrTest=&[initialmessage]&;
/**Calledwhentheactivityisfirstcreated.*/
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findAndModifyButton();
publicStringgetTestString()
returnstrT
//测试JAVA的NDK调用
publicnativeStringstringFromJNI();
//测试C/C++中对JAVA函数的静态回调
publicnativestaticintjniStaticShowMessage(Contextctx,StringstrTitle,StringstrMessage);
//测试实例中C/C++中对JAVA类的函数的调用
publicnativeintjniShowMessage(Contextctx,StringstrTitle,StringstrMessage);
//测试创建新实例C/C++对JAVA类的函数的调用
publicnativeintjniInstanceShowMessage(Contextctx,StringstrTitle,StringstrMessage);
System.loadLibrary(&demo-jni&);
staticintstaticShowMessage(Contextctx,StringstrTitle,StringstrMessage)
AlertDialog.Builderbuilder=newAlertDialog.Builder(ctx);
builder.setTitle(strTitle);
builder.setMessage(strMessage);
builder.setPositiveButton(&确定&,
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intwhichButton){
builder.show();
publicintshowMessage(Contextctx,StringstrTitle,StringstrMessage)
returnstaticShowMessage(ctx,strTitle,strMessage);
privatevoidfindAndModifyButton()
//测试JAVA的NDK调用
Buttonbtn01=(Button)findViewById(R.id.Button01);
btn01.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
TextViewtv=(TextView)findViewById(R.id.tv01);
tv.setText(stringFromJNI());
showMessage(JniDemoActivity.this,&JNItest1&,stringFromJNI());
//测试C/C++中对JAVA函数的静态回调
Buttonbtn02=(Button)findViewById(R.id.Button02);
btn02.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
intret=jniStaticShowMessage(JniDemoActivity.this,&JNItest2&,&teststaticcallbackMessage&);
TextViewtv=(TextView)findViewById(R.id.tv01);
if(ret==0)
tv.setText(&testJNIstaticcallbacksuccessed&);
tv.setText(&testJNIstaticcallbackfialed&);
//测试实例中C/C++中对JAVA类的函数的调用
Buttonbtn03=(Button)findViewById(R.id.Button03);
btn03.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
strTest=&[messagehaschangednow]&;
intret=jniShowMessage(JniDemoActivity.this,&JNItest3&,&testcallbackincurrentinstance&);
TextViewtv=(TextView)findViewById(R.id.tv01);
if(ret==0)
tv.setText(&testJNIcallbacksuccessed&);
tv.setText(&testJNIcallbackfialed&);
//测试创建新实例C/C++对JAVA类的函数的调用
Buttonbtn04=(Button)findViewById(R.id.Button04);
btn04.setOnClickListener(newButton.OnClickListener()
publicvoidonClick(Viewv)
strTest=&[messagehaschangednow]&;
intret=jniInstanceShowMessage(JniDemoActivity.this,&JNItest4&,&testcallbackinnewinstance&);
TextViewtv=(TextView)findViewById(R.id.tv01);
if(ret==0)
tv.setText(&testJNInewinstancesuccessed&);
tv.setText(&testJNInewinstancefialed&);
C代码demo-jni.cpp
view plaincopy
//加载此动态库时系统自动首先加载
jintJNI_OnLoad(JavaVM*vm,void*reserved)
if((*vm)-&GetEnv(vm,(void**)&env,JNI_VERSION_1_4)!=JNI_OK)
returnJNI_VERSION_1_4;
Java_study_jnidemo_JniDemoActivity_stringFromJNI(JNIEnv*env,jobjectthiz)
return(*env)-&NewStringUTF(env,&JniDemo,HellofromJNI!&);
combine_jstring(JNIEnv*env,jstringstr1,jstringstr2)
jbooleanb_
constchar*s1=(*env)-&GetStringUTFChars(env,str1,&b_ret);
constchar*s2=(*env)-&GetStringUTFChars(env,str2,&b_ret);
intn1=strlen(s1);
intn2=strlen(s2);
char*new_str=(char*)malloc(n1+n2+1);
memset(new_str,0,n1+n2+1);
strcat(new_str,s1);
strcat(new_str,s2);
jstringret_str=(*env)-&NewStringUTF(env,(constchar*)new_str);
free(new_str);
returnret_
Java_study_jnidemo_JniDemoActivity_jniStaticShowMessage(JNIEnv*env,jobjectthiz,
jobjectctx,jstringstrTitle,jstringstrMessage)
jclasscls=(*env)-&FindClass(env,&study/jnidemo/JniDemoActivity&);
//jclasscls=(*env)-&GetObjectClass(env,thiz);
if(cls!=NULL)
jmethodIDid=(*env)-&GetStaticMethodID(env,cls,
&staticShowMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(id!=NULL)
return(*env)-&CallStaticIntMethod(env,cls,id,ctx,strTitle,strMessage);
//在当前已有的JAVA实例中调用
Java_study_jnidemo_JniDemoActivity_jniShowMessage(JNIEnv*env,jobjectthiz,
jobjectctx,jstringstrTitle,jstringstrMessage)
jclasscls=(*env)-&GetObjectClass(env,thiz);
if(cls!=NULL)
jmethodIDstrTest_id=(*env)-&GetMethodID(env,cls,&getTestString&,
&()Ljava/lang/S&);
if(strTest_id!=NULL)
str=(*env)-&CallObjectMethod(env,thiz,strTest_id);
jmethodIDshowMessage_id=(*env)-&GetMethodID(env,cls,&showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id!=NULL)
return(*env)-&CallIntMethod(env,thiz,showMessage_id,ctx,
strTitle,combine_jstring(env,strMessage,str));
//在新建JAVA实例中调用
Java_study_jnidemo_JniDemoActivity_jniInstanceShowMessage(JNIEnv*env,jobjectthiz,
jobjectctx,jstringstrTitle,jstringstrMessage)
jclasscls=(*env)-&FindClass(env,&study/jnidemo/JniDemoActivity&);
if(cls!=NULL)
//getinstance
jmethodIDconstuctor_id=(*env)-&GetMethodID(env,cls,&&,&()V&);
if(constuctor_id!=NULL)
jobjectobj=(*env)-&NewObject(env,cls,constuctor_id);
if(obj!=NULL)
jmethodIDstrTest_id=(*env)-&GetMethodID(env,cls,&getTestString&,
&()Ljava/lang/S&);
if(strTest_id!=NULL)
str=(*env)-&CallObjectMethod(env,obj,strTest_id);
jmethodIDshowMessage_id=(*env)-&GetMethodID(env,cls,&showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id!=NULL)
return(*env)-&CallIntMethod(env,obj,showMessage_id,ctx,
strTitle,combine_jstring(env,strMessage,str));没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!豆丁微信公众号
君,已阅读到文档的结尾了呢~~
利用Java提供的C语言接口在Java中调用C函数
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
利用Java提供的C语言接口在Java中调用C函数
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='http://www.docin.com/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!}

我要回帖

更多关于 函数中调用结构体 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信