Java中调用C代码

Java中调用C代码

在Java中调用C代码通常通过Java本地接口(JNI,Java Native Interface)实现。以下是详细步骤和示例:

步骤 1:编写Java类并声明本地方法

public class NativeDemo {

// 声明本地方法(用native关键字修饰)

public native void printHello();

// 加载动态链接库(无需后缀)

static {

System.loadLibrary("nativeDemo");

}

public static void main(String[] args) {

new NativeDemo().printHello(); // 调用本地方法

}

}

步骤 2:生成JNI头文件

编译Java类:javac -d . NativeDemo.java

生成头文件(JDK 8+使用javac -h):javac -h . NativeDemo.java

生成的头文件NativeDemo.h内容如下:/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class NativeDemo */

#ifndef _Included_NativeDemo

#define _Included_NativeDemo

#ifdef __cplusplus

extern "C" {

#endif

JNIEXPORT void JNICALL Java_NativeDemo_printHello(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

步骤 3:编写C代码实现本地方法

创建NativeDemo.c文件,实现头文件中的函数:

#include

#include "NativeDemo.h" // 包含生成的头文件

JNIEXPORT void JNICALL Java_NativeDemo_printHello(JNIEnv *env, jobject obj) {

printf("Hello from C!\n");

}

步骤 4:编译C代码为动态链接库

Windows(生成DLL)

gcc -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared -o nativeDemo.dll NativeDemo.c

Linux/macOS(生成.so/.dylib)

linux 平台

gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -I. -shared -o libnativeDemo.so org_example_NativeDemo.c

/bin/ld: /tmp/ccIbZfkB.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC

/bin/ld: final link failed: Nonrepresentable section on output

collect2: error: ld returned 1 exit status

gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -I. -shared -fPIC -o libnativeDemo.so org_example_NativeDemo.c

mac 平台

gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -I. -shared -o libnativeDemo.dylib org_example_NativeDemo.c

步骤 5:运行Java程序

确保动态库在Java的库路径中,可以通过以下方式指定:

java -Djava.library.path=. -cp . org.example.NativeDemo

输出:

Hello from C!

关键注意事项

命名规则:C函数名必须遵循Java_ClassName_MethodName格式。类型映射:使用JNI类型(如jstring, jint)与C类型转换。JNIEXPORT jstring JNICALL Java_MyClass_getMessage(JNIEnv *env, jobject obj) {

return (*env)->NewStringUTF(env, "Message from C");

}

内存管理:通过JNIEnv方法管理资源(如NewStringUTF, GetStringUTFChars)。异常处理:在C代码中抛出Java异常:jclass exClass = (*env)->FindClass(env, "java/lang/Exception");

(*env)->ThrowNew(env, exClass, "Error in C code");

替代方案:JNA(Java Native Access)

如果希望简化流程,可以使用JNA库,无需编写JNI代码:

import com.sun.jna.Library;

import com.sun.jna.Native;

public class JNADemo {

public interface CLibrary extends Library {

CLibrary INSTANCE = Native.load("c", CLibrary.class);

void printf(String format, Object... args);

}

public static void main(String[] args) {

CLibrary.INSTANCE.printf("Hello from C via JNA!\n");

}

}

通过以上步骤,即可在Java中成功调用C代码。根据需求选择JNI或JNA,前者性能更高,后者更简单。

gitee源码地址

相关任务

www.bet3365.com 2011年国际足联女足世界杯

2011年国际足联女足世界杯

📅 07-21 👁️ 9333
365bet取款 韩语为什么那么难听

韩语为什么那么难听

📅 07-04 👁️ 3127
www.bet3365.com 高老夫子

高老夫子

📅 10-23 👁️ 2932
www.bet3365.com 2025年驾考科目二新规扣分细则全解析