JNI引用C++dll若干问题总结-如何导出C++中的类成员函数

3 篇文章 0 订阅

最近做项目使用JNI引用C++的dll,在此记录遇到的问题。

1.如何导出C++中的类
大家都知道JNI只能导出全局函数,至少我搜索了好久都没看到过有导出类的,貌似不可以。当然如果可以就更好了。

那么既然使用的是C++语言,如果不使用类的话,那还不如直接使用C。总之,面向对象编程就是比面向过程”艺术”。所以就遇到个问题,C++类中的成员函数如何使用JNI导出?JNI只能导出全局函数。

所以,我们可以采用一个折中的办法,为每一个类成员函数写一个全局导出函数,在cpp实现文件中new 一个类对象,在全局函数中使用这个类对象调用成员函数,最后写一个全局函数释放这个类对象。

例如:

//Dog.h

class Dog()
{
public:
    Dog();
    ~Dog();

    void eat(){std::cout<<"eat bone\n";};
    ...
}

要想通过JNI导出Dog类的eat成员函数,当然可以有多个成员函数,我们新建一个文件:

//export.h

#include "jni.h"

extern "C"
{

    JNIEXPORT void JNICALL JAVA_com_wj_demo_init(JNIEnv *env, jobject);
    JNIEXPORT void JNICALL JAVA_com_wj_demo_eat(JNIEnv *env, jobject);
    JNIEXPORT void JNICALL JAVA_com_wj_demo_release(JNIEnv *env, jobject);
}

因为成员函数必须使用类的实例调用,所以我们可以在export.cpp中实例化这个类:

//export.cpp

#include "Dog.h"

Dog *dog ;

JNIEXPORT void JNICALL JAVA_com_wj_demo_init(JNIEnv *env, jobject)
{
    dog = new Dog();
}

JNIEXPORT void JNICALL JAVA_com_wj_demo_eat(JNIEnv *env, jobject)
{
    dog->eat();
}

JNIEXPORT void JNICALL JAVA_com_wj_demo_release(JNIEnv *env, jobject)
{
    dog->~Dog();
}

这样大概就可以了。手写的代码,不保证能运行,但是就是这思路。

2.在java中System.loadLibrary()注意的问题

<1>如果是64为的jdk必须加载64位的dll,debug版本的和release版本的都没关系,可以相互调用,但是必须是64位的。

<2>必须先加载依赖库,比如你要引用的a.dll还引用着b.dll,就必须先使用System.loadLibrary加载b.dll,再加载a.dll,有时候一个dll依赖多个dll的时候,需要注意加载的顺序。

<3>有些64位的dll引用的竟然是32位的dll,竟然也能编译过了。比如,我的项目中引用libcurl.dll,再loadLibrary的时候,报 %1 libcurl不是win32应用程序,我就纳闷了。然后在dependency工具下看到其引用的SSLEAY32.dll和LIBEAY32.dll竟然是32位的,估计是系统目录下的,因为我引用的dll目录中没有这两个dll,如果没有找的话,编译Java程序的时候会报找不到依赖库,但是没报这个错,说明是在系统目录下找到的。所以,我找到了SSLEAY32.dll和LIBEAY32.dll这两个的64位版本的,就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值