将shared_ptr与SWIG Directors for Java一起使用
我开始了解SWIG,SWIG的最新版本(v3.0)似乎只能处理我开箱即用的所有内容,包括C 11功能,但是当涉及到时,我遇到了麻烦将shared_ptr与我的导演类一起使用.
我已经能够使shared_ptr与普通代理类一起工作了,但现在在我的导演上,似乎不支持开箱即用.它给了我自动生成的类型,如SWIGTYPE_p_std__shared_ptrT_MyDataType_t,并且正在生成一个损坏的接口,因为它没有使用代理类使用的相同类型. 我有一个简单的例子,说明我正在尝试做什么(在swig 3.0上使用swig -c –java Test.i运行): Test.i %module(directors="1") test %{ %} %include <std_shared_ptr.i> %shared_ptr(MyDataType) class MyDataType { public: int value; }; class NonDirectorClass { public: std::shared_ptr<MyDataType> TestMethod(); }; %feature("director") CallbackBaseClass; class CallbackBaseClass { public: virtual ~CallbackBaseClass() {}; virtual std::shared_ptr<MyDataType> GetDataFromJava() {}; }; 基本上我要做的是在Java中扩展CallbackBaseClass,我希望能够传递我的shared_ptr包装类型.非director类生成shared_ptr类型就好了.导向器类代理文件正确生成,但包装器中的SwigDirector_方法引用了错误的类型. 看起来我可以通过在任何地方将SWIGTYPE_p_std__shared_ptrT_MyDataType_t的类型更改为MyDataType来手动修复文件,但我希望有更多swig知识的人可以回答这个问题,这样就可以正确生成. 我有最好的线索是here,但我仍在试图弄清楚如何正确使用这些类型的地图,特别是对于shared_ptr而不是基本的原语. 更新: 文件says:
虽然它没有说明原因.如果有充分理由不在董事中使用shared_ptr,我想知道这对于swig director是不可能的.看起来使用你在其他地方使用的相同类型是有意义的.我希望答案是有可能的. 解决方法
最新版本的SWIG文档现在为:
为了使您的示例工作,我们似乎需要添加四个缺少的类型映射,directorin,directorout,javadirectorin和javadirectorout: %module(directors="1") test %include <std_shared_ptr.i> %{ #include <memory> #include <iostream> %} %shared_ptr(MyDataType) %feature("director") CallbackBaseClass; %typemap(javadirectorin) std::shared_ptr<MyDataType> "new $typemap(jstype,MyDataType)($1,true)"; %typemap(directorin,descriptor="L$typemap(jstype,MyDataType);") std::shared_ptr<MyDataType> %{ *($&1_type*)&j$1 = new $1_type($1); %} %typemap(javadirectorout) std::shared_ptr<MyDataType> "$typemap(jstype,MyDataType).getCPtr($javacall)"; %typemap(directorout) std::shared_ptr<MyDataType> %{ $&1_type tmp = NULL; *($&1_type*)&tmp = *($&1_type*)&$input; if (!tmp) { SWIG_JavaThrowException(jenv,SWIG_JavaNullPointerException,"Attempt to dereference null $1_type"); return NULL; } $result = *tmp; %} %inline %{ class MyDataType { public: int value; }; class NonDirectorClass { public: std::shared_ptr<MyDataType> TestMethod() { return std::make_shared<MyDataType>(); } }; class CallbackBaseClass { public: virtual ~CallbackBaseClass() {}; virtual std::shared_ptr<MyDataType> GetDataFromJava() = 0; }; void frobinate(CallbackBaseClass& cb) { std::cout << "In C++: " << cb.GetDataFromJava()->value << "n"; } %} 即使您只在示例中使用了directorout case,仍然需要directorin typemap使director_connect中的查找成功,因为它依赖于具有正确的描述符. 这四个类型映射与函数中的in,javain和javaout类型映射等效,但由于它们在控制器中的作用而相反. 它们不够完整,无法处理所有情况,但它们在您的示例中起作用.描述符中的$typemap调用需要比Ubuntu 14.04中包含的版本更新的SWIG 3版本 – 在我写的形式中,我测试的唯一版本是从主干中检出的.您可以手动编写描述符(这只是descriptor =“LMyDataType;”),但显然不那么通用.如上所述编写它的优点是它也将正确处理%rename指令.这不会正确处理包,因此你也必须在这种情况下再次手动编写它. 我能够测试并运行该示例,我添加了以下run.java: public class run extends CallbackBaseClass { public MyDataType GetDataFromJava() { MyDataType val = new MyDataType(); val.setValue(123); return val; } public static void main(String[] argv) { System.loadLibrary("test"); run r = new run(); System.out.println("In Java: " + r.GetDataFromJava().getValue()); test.frobinate(r); } } 编译并运行它: ~/swig-trunk/preinst-swig -Wall -c++ -java test.i clang++-3.6 -stdlib=libc++ -Wall -Wextra -std=c++1y test_wrap.cxx -o libtest.so -I/usr/lib/jvm/default-java/include/ -I/usr/lib/jvm/default-java/include/linux -shared -fPIC javac run.java LD_LIBRARY_PATH=. java run 哪个跑的时候给了: In Java: 123 In C++: 123 我猜想在带有shared_ptr导演的Java的情况下,使描述符正确的微妙之处可能是让这个“正常工作”开箱即用的主要障碍. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |