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

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

我是 swig 的新手,已经通读了文档,但仍在挣扎。

在我的图书馆 header 我有以下 class:

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

在您的示例中,由于 'constness' 上的不匹配,类型映射未被应用。 (您的函数采用 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;
     = &tmp;
    JCALL2(ReleaseStringUTFChars, jenv, $input, str);
}

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

这样做可以在 in 类型映射中节省更多的 JNI 调用,这将不可避免地最终调用几个函数来最终获得字符串表示。

(编译通过,但我没有 运行)。