Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用SWIG包装std::function对象?_Java_C++_C++11_Swig_Std Function - Fatal编程技术网

Java 如何使用SWIG包装std::function对象?

Java 如何使用SWIG包装std::function对象?,java,c++,c++11,swig,std-function,Java,C++,C++11,Swig,Std Function,我见过不少类似的问题,但还没有找到解决我这个问题的办法。我正在尝试编写一些使用std::function的C++11代码,以便在Java应用程序中使用它 我遇到过这样的共享指针: virtual std::shared_ptr<some::ns::TheThing> getTheThing(unsigned short thingID); virtual std::vector<std::shared_ptr<some::ns::TheThing>> get

我见过不少类似的问题,但还没有找到解决我这个问题的办法。我正在尝试编写一些使用std::function的C++11代码,以便在Java应用程序中使用它

我遇到过这样的共享指针:

virtual std::shared_ptr<some::ns::TheThing> getTheThing(unsigned short thingID);
virtual std::vector<std::shared_ptr<some::ns::TheThing>> getAllTheThings() const = 0;
 void registerThingCallback(std::function<void(std::shared_ptr<some::ns::TheThing>) > func);
我遇到过这样的共享指针向量:

virtual std::shared_ptr<some::ns::TheThing> getTheThing(unsigned short thingID);
virtual std::vector<std::shared_ptr<some::ns::TheThing>> getAllTheThings() const = 0;
 void registerThingCallback(std::function<void(std::shared_ptr<some::ns::TheThing>) > func);
不幸的是,来自简单Java主代码的大多数方法现在都获取或返回这些对象,这使得它们相当不可用。你知道怎么解决这个问题吗?谢谢大家!

更详细一点的完整性:我使用以下三个脚本来编译和运行代码。参数略有不同,但我认为这无关紧要。在我这方面,它被设置为一个EclipseMaven项目。这些脚本位于我的项目的根目录中,头文件和swig文件位于src/main/resources中,java源文件位于src/main/java中,java编译类位于target/classes中。Eclipse执行java编译

swigthing.sh compileThingSwigTest.sh runThingTest.sh 最后更新
修复了上面的代码,将正确的参数传递给std_函数。现在,在问题和答案之间有一个完整的工作示例,说明了我所追求的。

尽管SWIG不提供std_功能。我认为我们可以自己构建一个,这需要一些工作。这里我的答案是我的a的一个更一般化的版本,针对一个特定的实例研究这个问题,并以Python为目标。我将对它进行多次迭代,为泛型
std::function
包装定义一个
%std\u函数

我假设您希望通过包装
std::function
实现四件事,这成为我们的主要需求:

  • 我们希望能够从Java代码中调用
    std::function
    对象
  • 包装的
    std::function
    对象需要像任何其他对象一样传递,包括在任意方向跨越语言边界
  • <> LI>在java中可以编写<代码>函数:函数> <代码>对象,它可以在不修改现有C++代码的情况下运行,而C++代码在<代码> STD::函数< /COD>对象(即保持类型擦除<代码> STD::函数< /COD>跨语言)
  • 应该能够使用C++函数函数类型指针构造java中的<代码>函数:函数< /COD>对象。 我将完成这些工作,并展示我们如何实现这一目标。在可能的情况下,我也将保持解决方案语言的不可知性

    为了讨论的目的,我对你问题中的
    shared\u ptr
    部分进行了润色,它实际上并没有改变任何事情,因为当你在
    shared\u ptr
    工作时,它实际上也足以在这个场景中使用,这只会让我的示例变得更加冗长,不必要

    我正在研究的解决方案实际上是根据SWIG中现有的
    shared_ptr
    支持建模的。我准备了一个测试界面来说明如何使用它:

    %模块测试
    %包括“std_function.i”
    %std_函数(函子,void,int,double);
    %{
    #包括
    %}
    %内联%{
    std::函数make_函子(){
    返回[](整数x,双y){
    std::cout call(对于每个(转发,虚拟参数));
    });
    }
    }
    };
    }
    %enddef
    

    和Test.I略微扩展,以验证java > C++传递的<>代码>:函数:< /Cord>对象,使能执行器:

    %模块(directors=“1”)测试
    %包括“std_function.i”
    %std_函数(函子,void,int,double);
    %{
    #包括
    无效添加和打印(整数a,双b){
    
    std::cout你的目标语言是什么?这是一个起点,但也有其他选择。D'oh刚刚看到Java标签。我会在周末尝试找到答案。如果不清楚的话,很抱歉,是的,是Java。提前谢谢你,同时我会看你发布的链接。哇,这是一个(典型的,让你看看你的历史)回答得很好。我仍在完成你今天早些时候发布的前半部分,我需要一点时间来完成和消化所有这些。我要么跟进问题,要么在感觉良好时接受。谢谢!我马上就有一个问题是,这是否适用于swig 3.0?@据我所知的可变模板否认SWIG 3.0中的ate支持仍然不足以正确处理
    std::function
    ,但我所写的应该在可预见的将来仍然有效。@否认我刚才所做的两次编辑中的第一次修复了一系列错误,一次是我昨天在回答中提到的垃圾收集问题,另一次是停止了完整的sol如果你调用这个类而不是
    Functor
    ,那么它就正常工作了。好的,我已经有机会解决了这个问题,并且在问题中发布了一个新的细节更新。
    #ifndef THE_THING_H
    #define THE_THING_H
    
    #include <string>
    
    namespace some {
      namespace ns {
    
        class TheThing {
        public:
    
            virtual ~TheThing() {};
    
            virtual unsigned long longThing() const = 0;
    
            virtual std::string stringThing() const = 0;
        };
      }
    }
    
    #endif  /* THE_THING_H */
    
    %module(directors="1") Thing
    %include "stl.i"
    %include "std_function.i"
    %include "std_shared_ptr.i"
    
    %shared_ptr(some::ns::TheThing);
    
    
    %typemap(javadirectorin) std::shared_ptr<some::ns::TheThing> "new $typemap(jstype, some::ns::TheThing)($1,false)";
    %typemap(directorin,descriptor="Lsome.ns.typemap(jstype, some::ns::TheThing);") std::shared_ptr<some::ns::TheThing> %{
         *($&1_type*)&j$1 = &$1;
    %}
    
    
    %include "test_thing.h"
    %include "thing_callback.h"
    
    %{
    #include <memory>
    
    #include "test_thing.h"
    #include "thing_callback.h"
    
    %}
    
    %std_function(Functor, void, std::shared_ptr<some::ns::TheThing>);
    
    %{
    #include <iostream>
    void add_and_print(std::shared_ptr<some::ns::TheThing> thing) {
      std::cout << "here\n";
    }
    %}
    
    %callback("%s_cb");
    void add_and_print(std::shared_ptr<some::ns::TheThing>);
    %nocallback;
    
    %inline %{
      std::function<void(std::shared_ptr<some::ns::TheThing>)> make_functor() {
        return [](std::shared_ptr<some::ns::TheThing>){
          std::cout << "make functor\n";
        };
      }
    
      void do_things(std::function<void(std::shared_ptr<some::ns::TheThing>)> in) {
          std::cout << "inside do things\n";
      }
    %}
    
    SWIGTYPE_p_f_std__function__f_std__shared_ptr__some__ns__TheThing____void____void
    SWIGTYPE_p_f_std__shared_ptr__some__ns__TheThing____void
    SWIGTYPE_p_std__functionT_void_fstd__shared_ptrT_some__ns__TheThing_tF_t
    
    MODULE_NAME=Thing
    PACKAGE=some.ns
    OUTDIR=./src/main/java/some/ns
    I_FILE=./src/main/resources/func_thing_test.i
    
    mvn clean
    
    rm $OUTDIR/*.*
    mkdir -p $OUTDIR
    
    swig -java -c++ -module $MODULE_NAME -package $PACKAGE -outdir $OUTDIR $I_FILE
    
    ./compileThingSwigTest.sh
    
    #!/bin/bash
    
    pushd src/main/resources
    g++ -c -std=gnu++11 -fpic \
    func_thing_test_wrap.cxx \
    -I/usr/lib/jvm/java/include \
    -I/usr/lib/jvm/java/include/linux
    
    g++ -shared func_thing_test_wrap.o -o libFunc.so
    popd
    
    pushd target/classes
    java -Xmx512M -Xms512M -Djava.library.path=. some.ns.test.RunThingTest
    popd
    
    %std_function(Name, Ret, ...)
    
    public class run {
        public static void main(String[] argv) {
            System.loadLibrary("test");
            test.make_functor().call(1,2.5);
        }
    }
    
    // Conversion constructor from function pointer
    function<Ret(__VA_ARGS__)>(Ret(*const)(__VA_ARGS__));
    
    public class run {
        public static void main(String[] argv) {
        System.loadLibrary("test");
        test.make_functor().call(1,2.5);
        new Functor(test.add_and_print_cb).call(3,4.5);
        }
    }
    
    public class run extends Functor {
        public static void main(String[] argv) {
            System.loadLibrary("test");
            test.make_functor().call(1,2.5);
    
            new Functor(test.add_and_print_cb).call(3,4.5);
    
            Functor f = new run();
            test.do_things(f);
        }
    
        @Override
        public void call(int a, double b) {
            System.out.println("Java: " + a + ", " + b);
        }
    }
    
    %extend {
      function<Ret(__VA_ARGS__)>(Name##Impl *in) {
        return new std::function<Ret(__VA_ARGS__)>([=](auto&& ...param){
          return in->call(std::forward<decltype(param)>(param)...);
        });
      }
    }
    
    %shared_ptr(some::ns::TheThing);
    %typemap(javadirectorin) std::shared_ptr<some::ns::TheThing> "new $typemap(jstype, some::ns::TheThing)($1,false)";
    %typemap(directorin,descriptor="L$typemap(jstype, some::ns::TheThing);") std::shared_ptr<some::ns::TheThing> %{ 
      *($&1_type*)&j$1 = &$1;
    %}