如何在c++中调用java代码

如何在c++中调用java代码,第1张

C语言调用Java,还有Java调用C,都使用到JNI技术,C语言调用需要创建Java虚拟机,可查看函数JNI_CreateJavaVM、DestroyJavaVM的资料,函数声明在jni.h头文件(JDK)中。需注意参数类型转换,两种语言的参数类型和传递有讲究,有多个返回的话,必须传递对象参数进行处理。

从java里调用c等其他语言的,是jni

从c等语言调用java的,要看你调用什么了,比如如果是java swing程序,可以用exe4j把它生成exe文件,用c去调用exe。如果是webservice,可以用soaptoolkit,是一个c++的库,可以访问WebService的,用的是soap。

1. 编写并编译J2C.java

import java.lang.management.ManagementFactory

import java.lang.management.RuntimeMXBean

public class J2C

{

static

{

try{

// 此处即为本地方法所在链接库名

System.loadLibrary("j2c")

} catch(UnsatisfiedLinkError e)

{

System.err.println( "Cannot load J2C library:\n " +

e.toString() )

}

}

//声明的本地方法

public static native int write2proc(int pid)

public static void main(String[] args){

//获取本进程(即主线程)的pid

final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean()

final String info = runtime.getName()

final int index = info.indexOf("@")

if (index != -1) {

final int pid = Integer.parseInt(info.substring(0, index))

System.out.println(info)

System.out.println(pid)

write2proc(pid)

}

try{

Thread.sleep(8000)

} catch(InterruptedException e){

e.printStackTrace()

}

}

}

note:Java程序中System.loadLibrary参数名表示要载入的C/C++共享库,第6步生成的共享库名必须与该参数一致,即System.loadLibrary(Name) 对应共享库名libName.so (共享库名必须以lib开头)

2. 生成C头文件J2C.h:javah J2C

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class J2C */

#ifndef _Included_J2C

#define _Included_J2C

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: J2C

* Method: write2proc

* Signature: (I)I

*/

JNIEXPORT jint JNICALL Java_J2C_write2proc

(JNIEnv *, jclass, jint)

#ifdef __cplusplus

}

#endif

#endif

note:1. 头文件自动生成,不要修改它;

2. 函数JNIEXPORT jint JNICALL Java_J2C_write2proc(JNIEnv *, jclass, jint)

按照注释的说明是在J2C.java文件的类J2C的方法write2proc处定义,故C程序的实现函数必须与该处签名一致;

3. 编写C程序J2C.c

#include <stdio.h>

#include "J2C.h"

JNIEXPORT int JNICALL Java_J2C_write2proc(JNIEnv * env, jobject arg, jint pid)

{

printf("current pid is %d\n", pid)

return 0

}

4. 编译C程序

因为C程序里#include "J2C.h"而J2C.h又#include <jni.h>, 而gcc里面默认环境并不知道jni.h是什么东西,故编译时需要告诉编译器jni.h的位置( jni.h在jdk 的$JAVA_HOME/include下面),所以才有了上面的编译参数;

因为使用gcc编译得到动态库,在jni调用的时候,某些情况会有异常, 可尝试改用g++。

总结

1. Java中方法的原型声明与C/C++对应的实现文件定义必须一致(可以通过自动生成的C/C++头文件来比较),尤其是类名和方法名;

2. Java中System.loadLibrary()载入的共享库名必须与后面C/C++生成的共享库名一致。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12090066.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-20
下一篇2023-05-20

发表评论

登录后才能评论

评论列表(0条)

    保存