您将如何配置SWIG .i文件以处理C FILE *类型?下面的函数设置一个文件,以便可以将日志输出写入该文件。我需要从Java类中调用。当前,当我仅将C头文件包含在以下函数中时,SWIG将生成公共静态void setLogFile(SWIGTYPE_p_FILE fd)函数。有任何想法吗?
C函数:
void setLogFile(FILE *fd);
我尝试使用以下方法#1并得到以下异常:
test.i:
%module Example %{ #include "headerLogFile.h" %} %inline %{ void setLogFile(const char *fn) { FILE *f = fopen(fn, "w"); setLogFile(f); } %} %ignore setLogFile; %include "headerLogFile.h"
例外:
[exec] test_wrap.c:193: error: conflicting types for 'setLogFile' [exec] /test/include/headerLogFile.h:96: error: previous declaration of 'setLogFile' was here [exec] test_wrap.c: In function `setLogFile': [exec] test_wrap.c:195: warning: passing arg 1 of `setLogFile' from incompatible pointer type
给定的test.h看起来像:
test.h
#include <stdio.h> 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 <cassert> %} // 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
java.io.FileDescriptor
FileDescriptor
FileOutputStream
getFD()
private static
setLogFile