Swig java.nio.file.Path <-> boost :: filesystem :: path - PullRequest
0 голосов
/ 21 ноября 2018

Я новичок в Swig и прочитал документацию, но все еще не могу.

В заголовке моей библиотеки есть следующий класс:

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

Я пытаюсь получить еготак что пользователи могут передавать java.nio.file.Path из кода Java через слой JNI, созданный swig.Вот мой файл определения 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 Ответ

0 голосов
/ 24 ноября 2018

В вашем примере карты типов не применялись из-за несоответствия по "constness".(Ваша функция принимает const boost::filesystem::path &path, но ваши карты типов предназначены для boost::filesystem::path &, поэтому не могут быть применены).

Я думаю, что самый простой способ сделать эту работу - передать путь в виде строки черезязыковые границы.Вы можете сделать это с помощью следующих карт типов, которые на стороне Java вызывают toString() на пути, а на стороне C ++ передают это в конструктор для объекта пути повышения:

%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 карты типов, что неизбежно в конечном итоге вызовет несколько функций для получения строкового представления в конце.

(Это компилируется, но я не запускал его).

...