代码之家  ›  专栏  ›  技术社区  ›  Matthew Hoggan

swig java.nio.file.path<-->boost::filesystem::path

  •  2
  • Matthew Hoggan  · 技术社区  · 5 年前

    我刚接触Swig,已经阅读了文档,但仍在苦苦挣扎。

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

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

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

    %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 回复  |  直到 5 年前
        1
  •  1
  •   Flexo - Save the data dump sunny moon    5 年前

    在您的示例中,由于“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;
        $1 = &tmp;
        JCALL2(ReleaseStringUTFChars, jenv, $input, str);
    }
    
    %inline %{
        void test(const boost::filesystem::path& p) {
            std::cout << p << std::endl;
        }
    %}
    

    这样做可以节省更多的JNI调用 in typemap,它最终不可避免地会调用几个函数来获取一个字符串表示形式。

    (这是编译的,但我没有运行它)。