JAVA如何调用C函数

C里面写了一个类
class Demo
{
public:
struct MData{
char Code[7];
float Lng;
float Lat;
float Mem[30];
}
}

然后在H头文件里面有个函数
void MData_Load(Demo::MData *mData);

请问一下,在JAVA里面怎么生成这个类并调用这个加载函数?

要在java中调用c语言的库,需要使用Java提供了JNI。
举例说明
在c语言中定义一个 void sayHello()函数(打印Hello World);然后在Java中调用这个函数显示Hello Word.
现在分别从Java和C语言两部分说明:
1. Java 部分
首先定义一个HelloNative,在其中申明sayHello函数,函数要申明为Native 类型的.如下:
public class HelloNative {
public native void sayHello();
}

编译这个类,生成class文件:
javac HelloWorld.java

利用javah生成需要的h文件
javah HelloNative

生成的 h文件大概如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloNative
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloNative_sayHello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

可以看一下上面自动生成的程序,程序include了jni.h,这个头文件在 $JAVA_HOME下的include文件夹下. 还可以发现生成的函数名是在之前的函数名前面加上了Java_HelloNative。
2. C语言部分
根据上面生成的h文件编写相应的代码实现,建立一个 HelloNative.cpp用来实现显示Hello World的函数.如下:

#include <stdio.h>
#include "HelloNative.h"

JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *, jobject)
{
printf("Hello World!\n");
}

代码编写完成之后,我们再用gcc编译成库文件,命令如下;
gcc -fPIC -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include/linux -shared -o libHelloNative.so HelloNative.cpp

这样就会在当前目录下生成一个libHelloNative.so的库文件.这时需要的库已经生成,在C语言下的工作已经完成了.
接下来需要在Java中编写一个程序测试一下.在程序前,需要将我们的库载入进去.载入的方法是调用Java的 System.loadLibrary("HelloNative");

public class TestNative
{
static {
try {
System.loadLibrary("HelloNative");
}
catch(UnsatisfiedLinkError e) {
System.out.println( "Cannot load hello library:\n " + e.toString() );
}
}
public static void main(String[] args) {
HelloNative test = new HelloNative();
test.sayHello();
}
}

但是再编译后,运行的时候,问题又出现了.
Cannot load hello library:
java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloNative.sayHello()V
at HelloNative.sayHello(Native Method)
at TestNative.main(TestNative.java:13)

载入库失败,但是库明明就是放在当前文件夹下的,怎么会载入失败呢?
用System.getProperty("java.library.path")查看,发现java.library.path中并不u存在当前的目录.主要有以下的几个解决办法:
1) 将生成的库复制到java.library.path有的路径中去,当然这样不是很好
2) 设置环境变量export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ,将当前的目录加入到LD_LIBRARY_PATH中
3) 设置java 的选项,将当前的目录加入到其中 .java -Djava.library.path=. $LD_LIBRARY_PATH
这样之后程序就能够成功的运行了.可以看见显示的"Hello World!"了追问

谢谢你的帮助,不过似乎并没有解决我这个问题。

温馨提示:内容为网友见解,仅供参考
无其他回答

JAVA如何调用C函数
可以看一下上面自动生成的程序,程序include了jni.h,这个头文件在 $JAVA_HOME下的include文件夹下. 还可以发现生成的函数名是在之前的函数名前面加上了Java_HelloNative。2. C语言部分 根据上面生成的h文件编写相应的代码实现,建立一个 HelloNative.cpp用来实现显示Hello World的函数.如下:include <stdio...

JAVA如何调用C语言接口?
第一,jni方式调用c接口。通过将c语言接口封装为jni的方式直接供java语言调用,这个可以说是最惯用的方式。第二,jna方式调用c接口。jna也是其中一种调用c接口的方式。使用时可以加载动态库.dll或.so,然后调用库中的接口。第三,如果c接口很简单,可以将c接口编译为可执行程序,使用java直接调用可执行...

java怎么引用c
具体调用步骤如下:1.首先创建Java文件 HelloJni.java ,并创建native方法。2.编译Java文件并生成java头文件。3.创建C语言文件,HelloWorld.c。4.生成动态链接库文件 libhello.so。5.设置动态链接库文件的目录。6.把刚才生成的so文件拷贝到\/home\/lib下,然后执行class文件。

JAVA如何调用C语言编写的程序,并且传参数,读取返回结果?
(JNIEnv *, jobject, jintArray);ifdef __cplusplus } endif endif 这个文件主要是为了生成java调用c的主要方法,也即是上面的几个方法。3、用c语言的程序来实现上班生成的几个方法,即Sample1.c源代码如下:include "Sample1.h"include <string.h> JNIEXPORT jint JNICALL Java_Sample1_intMet...

用Java怎么调用C语言已经编写好的DLL?
{ return x > y ? x : y; } 备注: A 其中的jni.h通常在 jdk\\include\\ 可以先拷贝到VC安装目录下的include目录下.一劳永逸,以后可以方便使用JNI技术. B 全部的数据类型需要考虑Java和VC的接口问题.用jint jstring 等. C 函数名称和自动生成的.h文件中规定的一致.命名规则是: Java_使用类_...

什么样的技术能让java调用c语言的代码
java被编译成字节码后由JVM解释执行,java要调用C语言写的程序,那么就必须通过JVM调用,java告诉JVM我要调用本地操作系统的那个程序段(如dll)并要求返回一个结果。通过JVM调用本地程序的技术就是JNI,java Native interface(本地接口技术)。java是通过虚拟机实现跨平台技术的,因此要调用本地操作系统...

java用jna调用C语言dll接口中的回调函数怎么写
简单的你会写,那就好办,直接上代码 public interface TestAPI extends StdCallLibrary { interface LoginReply extends StdCallCallback { \/** * 登录回调 *\/ void invoke(String userId, long retCode, String retMsg); } \/** * 注册一个登录回调方法.此方法是dll提供的...

Java使用jna调用c++动态库(Linux)
为了开始,首先从官网下载并导入jna-5.9.0.jar库到项目。接下来,通过在Java项目中创建一个继承自Library接口的自定义接口,定义公共静态常量testSo,这个常量通过Native.load()函数加载动态库,参数分别是动态库名称和接口的Class类型。3.在接口中声明要调用的C\/C++函数,并确保Java与C++函数参数和返回...

java怎么在main函数调用其他类的方法
1先要在main函数所在的类引进你要调用的类的所在包,同一个包就不用导入(import)2然后在main方法中创建类对象,用对象调用该类中可以调用的方法 这是最基本的调用方法 public class Main{import com.java.cse;\/\/包含类CLassApublic static void main(String[] args){ ClassA myClassA =new ...

java一个方法如何引用另一个方法中的变量
a()b()c()函数可以设置返回值,在gs()里面调用三个函数,得到返回值

相似回答