简体   繁体   English

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

[英]Swig: How to pass “FILE” type from C++ to Java

I have a function in C++ for which I need to create a wrapper in Java. 我在C ++中有一个函数,需要为此使用Java创建包装器。 The function expects an input parameter of type FILE (from stdio). 该函数需要输入文件类型为FILE(来自stdio)。 I don't believe that Swig can automatically appropriate an interface in Java without some manual engineering in the swig interface file - I might be wrong. 我不认为Swig无需在swig接口文件中进行一些手动工程就可以自动使用Java中的接口-我可能是错的。

Here is what I have -- 这是我所拥有的-

C++ (theHeader.h): C ++(theHeader.h):

#include <cstdio>

class SampleClass 
{
 public:
  SampleClass(FILE* file) : file(file)
  {
  }

  private:
  FILE* file;
};

I have tried compiling, but it results in the creation of Swig pointer type: SWIGTYPE_p_FILE, which doesn't help me in passing the FILE type argument from Java to C++. 我已经尝试编译,但是它导致了Swig指针类型的创建:SWIGTYPE_p_FILE,这并没有帮助我将FILE类型参数从Java传递到C ++。

Why use SWIG for this? 为什么要使用SWIG? This is pretty trivial to do directly with JNI (assuming pointers fit into jlong values for your system's architecture, which is usually a pretty safe assumption): 直接使用JNI进行操作非常简单(假设指针适合系统体系结构的jlong值,这通常是一个非常安全的假设):

Java: Java:

// 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 );

You'd use it like this: 您可以这样使用它:

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

Or, if you already have the FILE * from native code: 或者,如果您已经拥有本机代码中的FILE *

long instance = getClassInstance( file );

Native C++ code would look something like this (I'm not bothering to do the full javac work from the above Java code): 本机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 );
}

Note that the code assumes that the native definition of NULL is always a zero value. 请注意,代码假定NULL的本机定义始终为零值。 Technically, JNI makes a C call, not a C++ call, so NULL might not be guaranteed to always be actually defined to be zero, depending on your architecture and how you code up your interface between Java and native code. 从技术上讲,JNI进行C调用,而不是C ++调用,因此可能无法保证NULL实际上总是定义为零,具体取决于您的体系结构以及如何编写Java与本机代码之间的接口。 So to be fully standard compliant, a NULL pointer result would cause the jlong value returned to Java to be explicitly set to zero. 因此,要完全符合标准, NULL指针结果将导致返回Java的jlong值显式设置为零。 The reverse works because a zero value is defined by the C Standard to be a NULL pointer value that compares equal to the defined NULL pointer constant. 反向工作,因为零值由C标准定义为一个 NULL ,其比较等于规定的指针值NULL指针恒定。 (Note that there can be more than one " NULL pointer value" even though there's only one definition of NULL itself.) (请注意,即使只有一个NULL本身定义,也可以有多个“ NULL指针值”。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM