java中file中参数,SWIG配置以处理Java中的FILE * C输入参数

本文详细介绍了如何使用SWIG将C++的setLogFile函数包装到Java中,提供了三种不同的方法:直接包装、包裹更多stdio.h函数和使用FileOutputStream接口。每种方法都有其优缺点,并涉及到JNI转换、类型映射和异常处理等方面的技术细节。
摘要由CSDN通过智能技术生成

小编典典

给定的test.h看起来像:

#include

inline void setLogFile(FILE *fd) {

fprintf(fd, "Test\n");

fflush(fd);

}

我可以看到您可能会选择使用三种方法来包装此函数:

方法1-String从Java传递a :

向Java公开一个函数,该函数期望文件名以而String不是a形式传递FILE*:

%module method1

%{

#include "test.h"

%}

%inline %{

void setLogFile(const char *fn) {

FILE *f = fopen(fn, "w");

setLogFile(f);

}

%}

这用于%inline指示SWIG在定义该函数的同时包装该函数。如果仍然使用,%include “test.h”则可能要对SWIG隐藏原始版本。

方法2-包装更多stdio.h:

包裹不止setLogFile,包裹的东西喜欢fopen,fmemopen等适当的。(我个人不太喜欢这种解决方案,因此我没有举一个例子)

方法3-公开一个带有以下内容的Java接口FileOutputStream:

%module method3

%{

#include "test.h"

#include

%}

// 3:

%typemap(jni) FILE *fd "jobject"

// 1:

%typemap(jstype) FILE *fd "java.io.FileOutputStream"

// 2:

%typemap(jtype) FILE *fd "java.io.FileDescriptor"

// 4:

%typemap(in) (FILE *fd) {

jfieldID field_fd;

jclass class_fdesc;

int rawfd;

class_fdesc = jenv->FindClass("java/io/FileDescriptor");

assert(class_fdesc);

field_fd = jenv->GetFieldID(class_fdesc, "fd", "I");

assert(field_fd);

rawfd = jenv->GetIntField($input, field_fd);

$1 = fdopen(rawfd, "w");

// Add some code to throw a Java exception if $1 is NULL (i.e. error)

}

// 5:

%typemap(javain, pre=" retainFD = $javainput;",

throws="java.io.IOException") FILE *fd "$javainput.getFD()"

// 6:

%pragma(java) modulecode=%{

private static java.io.FileOutputStream retainFD;

%}

%include "test.h"

这将执行以下操作:

我们希望输入到模块的实际公共部分java.io.FileOutputStream。

但是,JNI代码的Java端将改为使用java.io.FileDescriptor。

JNI代码的C ++端将其视为 jobject

在C ++方面,我们将做一些有点邪恶的事情-读取类中的私有int字段FileDescriptor(请参见此处)。这可能不是便携式和阅读类私处通常被认为是不好的,但它使我们能够得到的东西我们可以通过fdopen()得到一个FILE*“真正”的号召

通常,此类型图接受FileOutputStream并对其进行调用getFD()以获取其FileDescriptor对象。它还添加了一个异常规范以匹配getFD()并执行另一个功能,这是下一点的一部分

我们需要确保Java不会垃圾回收并完成FileOutputStream,这将关闭文件句柄并使我们的无效FILE*。我们通过FileOutputStream在private static变量中引用我们来实现。在pre=”…以前的类型映射的原因最近的一次被保留,直到我们切换到另一个。(如果我们打电话setLogFile两次,那没关系,实际上释放我们对前一个的引用是件好事FileOutputStream)

2020-12-01

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值