Swig java.nio.file.Path <-> boost :: filesystem :: path

时间:2018-11-21 15:18:29

标签: java c++ java-native-interface swig

我是个新手,已经阅读了文档,但是仍然很挣扎。

在我的库标题中,我有以下课程:

class Facade
{
public:
  static bool Init(const boost::filesystem::path &path);
};

我正在尝试获取它,以便用户可以通过swig创建的JNI层从Java代码传递java.nio.file.Path。这是我的痛饮定义文件:

%module FacadeInterface
%{
#include "Facade.h"
#include <boost/filesystem/path.hpp>
%}
%pragma(java) jniclassimports=%{
import java.nio.file.Path;
%}
%pragma(java) moduleimports=%{
import java.nio.file.Path;
%}
%typemap(jstype) boost::filesystem::path & "java.nio.file.Path"
%typemap(jstype) boost::filesystem::path "java.nio.file.Path"
%typemap(jtype) boost::filesystem::path & "java.nio.file.Path"
%typemap(jtype) boost::filesystem::path "java.nio.file.Path"
%typemap(jni) boost::filesystem::path & "jobject"
%typemap(jni) boost::filesystem::path "jobject"
%typemap(in) boost::filesystem::path {...}
%typemap(in) boost::filesystem::path & {...}
%typemap(out) boost::filesystem::path {...}
%typemap(out) boost::filesystem::path & {...}
%include "Facade.h"

这只能部分起作用,因为Java代码会构建一个使用java.nio.file.Path的接口,然后尝试将其转换为SWIGTYPE_p_boost__filesystem__path。例如,生成的代码显示为。

public class Facade {
    ...
    public static boolean Init(java.nio.file.Path path) {
        return FacadeInterfaceJNI.Facade_Init(
            SWIGTYPE_p_boost__filesystem__path.getCPtr(path));
    }
    ...
  }

我需要做什么才能将java.nio.file.Path转换为boost::filesystem::path

我的Java编译器错误如下:

/root/build/src/main/com/Facade.java:39: error: incompatible types: Path cannot be converted to SWIGTYPE_p_boost__filesystem__path
    return FacadeInterfaceJNI.Facade_Init(SWIGTYPE_p_boost__filesystem__path.getCPtr(modelPath));

1 个答案:

答案 0 :(得分:1)

在您的示例中,由于“常量”不匹配,因此未应用类型映射。 (您的函数使用const boost::filesystem::path &path,但是您的类型映射用于boost::filesystem::path &,因此无法应用。)

我认为完成这项工作的最简单方法是将路径作为字符串传递穿过语言边界。您可以使用以下类型映射来做到这一点,这些类型映射在Java端在路径上调用toString(),在C ++端将其传递给boost路径对象的构造函数:

%module test

%{
#include <boost/filesystem/path.hpp>
#include <iostream>
%}

%typemap(jni) const boost::filesystem::path& "jstring"
%typemap(jstype) const boost::filesystem::path& "java.nio.file.Path"
%typemap(jtype) const boost::filesystem::path& "String"
%typemap(javain) const boost::filesystem::path& "$javainput.toString()"
%typemap(in) const boost::filesystem::path& (boost::filesystem::path tmp) {
    const char *str = JCALL2(GetStringUTFChars, jenv, $input, 0);
    tmp = str;
    $1 = &tmp;
    JCALL2(ReleaseStringUTFChars, jenv, $input, str);
}

%inline %{
    void test(const boost::filesystem::path& p) {
        std::cout << p << std::endl;
    }
%}

这样做可以将更多的JNI调用保存在in类型映射中,这将不可避免地导致最终调用了多个函数以最终获得字符串表示形式。

(这可以编译,但是我还没有运行)。