当前位置: 首页 > 知识库问答 >
问题:

Swig:如何将“文件”类型从C传递到Java

洪雅健
2023-03-14

我在C中有一个函数,我需要在Java中创建一个包装器。该函数期望FILE类型的输入参数(来自标准输入输出)。我不相信Swig可以在Java中自动适应一个接口,而不需要在Swig接口文件中进行一些手动工程-我可能错了。

这是我所拥有的

C(标题h):

#include <cstdio>

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

  private:
  FILE* file;
};

我尝试过编译,但结果是创建了Swig指针类型:SWIGTYPE_p_FILE,这无助于我将FILE type参数从Java传递到C。

共有1个答案

夏侯林
2023-03-14

为什么要用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 );
}

或者,如果您已经拥有本机代码中的文件*

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 Standard将零值定义为NULL指针值,该指针值与定义的NULL指针常量进行比较。(请注意,即使NULL本身只有一个定义,也可以有多个“NULL指针值”。)

 类似资料:
  • 问题内容: 我在C 中有一个方法,该方法将双精度数组作为参数。我从Java调用此方法,需要传递一个双精度数组。C 例程读取和修改数组的值,而我需要Java中的那些更新后的值。我该怎么做呢? 例如,使用C ++例程: 和Java代码: 我猜不能像上面的调用那样对myMethod进行调用…还是可以吗?而在Swig中进行这项工作所需的是什么。如果我无法进行上述调用,如何将我的值获取到C ++代码? 问题

  • 我正在使用TestNG执行单元测试,其中我正在使用xml文件中定义的测试用例测试我的代码。 我正在使用xml文件中定义的测试用例执行登录操作。但问题是我想在方法登录中以usersname和password的形式发送参数。 是否可以将值(用户名和密码)传递给执行测试用例的xml文件中的登录方法? 下面是我的XML文件 谢谢

  • 因此,我想要做的是使用Gradle运行我的Java应用程序,但也要将一个。csv&.xml文件传递给我的主类,以便在我的bufferedReader中使用它们&我不知道应该怎么做。我的应用程序不是构建到jar,它应该是用gradle运行任务运行的。我希望用户能够指定他们自己要使用的xml和csv文件(在命令行中),然后运行Java应用程序,而不是询问应用程序中文件的路径。例如,让我们使用这行代码:

  • 问题内容: 我知道clojure / java互操作的基础:从clojure调用Java,反之亦然。但是,我无法将类型的集合从clojure返回到Java。我试图从正在调用clojure的Java代码中看到这种性质的东西。 让我们考虑一下,我正在使用clojure编写API,该API将作为jar文件分发,可以从Java使用。我的问题确实是如何代替???AOT的:gen- class里面有问号,因此

  • 我有一个集群,有两个工人和一个主人。为了启动master和workers,我在master计算机中使用和。然后,master UI向我显示奴隶还活着(所以,到目前为止一切正常)。当我想使用时,问题就出现了。 我在本地计算机中执行以下命令: 但是会弹出以下错误: 我一直在研究stack overflow和Spark的文档,似乎应该将命令的指定为“绑定jar的路径,包括应用程序和所有依赖项。URL必须

  • 我该怎么做? 更新:在搜索Github(包括Raku规范测试)之后,在这里,我没有找到任何通过CArray(结构)的例子。下面是Christoph在2017年发表的一篇文章,其中给出了一个“解决方案”。 克里斯托夫的解决方案可能有效,但如果没有更好的办法,在NativeCall中效果会更好。 在Github上有一个Rakudo测试,它使用了,如果您可以编写一个C函数来重新打包其参数以转发到,这可能