Swig:如何将"FILE"类型从 C++ 传递给 Java



我在C++中有一个函数,我需要用Java创建一个包装器。该函数需要 FILE 类型的输入参数(来自 stdio)。我不相信 Swig 可以在 Java 中自动占用接口,而无需在 swig 接口文件中进行一些手动工程 - 我可能是错的。

这是我所拥有的——

C++ (theHeader.h):

#include <cstdio>
class SampleClass 
{
public:
SampleClass(FILE* file) : file(file)
{
}
private:
FILE* file;
};

我尝试过编译,但它导致创建 Swig 指针类型:SWIGTYPE_p_FILE,这对我将 FILE 类型参数从 Java 传递到 C++ 没有帮助。

为什么要使用 SWIG? 直接使用 JNI 来说,这是非常简单的(假设指针适合系统架构的jlong值,这通常是一个非常安全的假设):

爪哇岛:

// get an instance of the native C++ class
static native long getClassInstance();
static native long getClassInstance( long file );
// get the native FILE * from the class instance
static native long getFileFromClass( long cls );
// close the FILE *
static native void closeFile( long file );

你可以像这样使用它:

long file = 0;
long cls = getClassInstance();
if ( cls != 0 )
{
file = getFileFromClass( cls );
}

或者,如果您已经拥有来自本机代码的FILE *

long instance = getClassInstance( file );

本机C++代码看起来像这样(我懒得从上面的 Java 代码中完成完整的javac工作):

JNIEXPORT jlong JNICALL some_class_getClassInstance(
JNIenv *env, jclass cl )
{
myClass *cls = new MyClass();
return( ( jlong )( intptr_t ) cls );
}
JNIEXPORT jlong JNICALL some_class_getClassInstance(
JNIenv *env, jclass cl, jlong file )
{
FILE *fp = ( FILE * )( intptr_t ) file;
myClass *cls = new MyClass( fp );
return( ( jlong )( intptr_t ) cls );
}
JNIEXPORT jlong JNICALL some_class_getFileFromClass(
JNIenv *env, jclass cl, jlong cls )
{
myClass *instance = ( myClass * )( intptr_t ) cls;
FILE *fp = myClass->getFile();
return( ( jlong )( intptr_t ) fp );
}
JNIEXPORT void JNICALL some_class_name_closeFile(
JNIenv *env, jclass cls, jlong file )
{
FILE *fp = ( FILE * ) ( intptr_t ) file;
fclose( fp );
}

请注意,代码假定NULL的本机定义始终为零值。 从技术上讲,JNI 进行 C 调用,而不是C++调用,因此可能无法保证NULL始终实际定义为零,具体取决于您的体系结构以及您在 Java 和本机代码之间的接口编码方式。 因此,为了完全符合标准,NULL指针结果将导致返回到 Java 的jlong值显式设置为零。 反之亦然,因为 C 标准将零值定义为定义的NULL指针常量相等的NULL指针值。(请注意,可以有多个"NULL指针值",即使NULL本身只有一个定义。

最新更新