我需要用 SWIG 包装一个 C++ 库才能将它与 Java 一起使用。
我已经有一些方法可以工作,但是我遇到了一种我不知道如何解决的情况。
我有几个这样的方法:
void method1(std::string & name, std::string & result);
bool method2(std::string & name, std::string & alias, std::string & resurnValue, std::string & returnType);
注意:实际上这是一个名为 MyClass 的类的成员方法。
我可以将第一个方法更改为返回 astd::string
而不是 being void
,这应该可以;但我不知道如何处理最后两个参数是输出参数的第二种方法。我已经看到了几个关于char *
输出参数的问题(使用 Swig/Python 在 C 中传递多个参数和分配字符串),但在我的情况下应该是 astd::string
并且 SWIG 的文档没有提到这种情况,请在此处输入链接描述。此外,我可能会遇到更多返回 3 个或更多输出参数的方法,可能具有不同的类型。
最后,我对接口有了一点控制,我还在开发一个作为库入口点的类,但它只是将调用传递给真正的实现。
例如,通过这个我已经设法改变了一个方法method3(std::string & s)
,method3(const std::string & s)
所以我可以从 Java 中使用它String
。
所以稍微修改方法签名是可能的,但如果一个本地方法返回 n 个输出参数,我应该返回所有参数(我不能创建新方法来返回每个参数)。
更新: 我一直在研究 Flexo 提供的解决方案并且效果很好,但是我正在考虑做一个类来包装 std::string 并使用它与返回的字符串进行交互,这是与 Flexo 的第二种解决方案非常相似的方法,但是使用这个 StringWrapper 而不是使用 java String 数组,基本上看起来像这样:
/*
* The MyClass.i file
*/
%module example
%include "std_string.i"
%{
class StringPtr{
private:
stdString str;
public:
StringPtr(){
}
StringPtr(const stdString & str){
this->str = stdString(str);
}
stdString & getStrRef(){
return (this->str);
}
stdString getStrVal(){
return stdString(this->str);
}
~StringPtr(){
}
};
%}
/////////////////// Export StringPtr to Java
class StringPtr{
public:
StringPtr();
StringPtr(const stdString & str);
stdString getStrVal();
~StringPtr();
};
// I think this is nor necessary
%rename ("$ignore", fullname=1) "StringPtr::getStrRef";
%extend MyClass {
void method1(cons std::string & name, StringPtr & result){
$self->method1(name, result.getStrRef());
}
bool method2(cons std::string & name, cons std::string & alias, StringPtr & returnValue, StringPtr & returnType){
$self->method2(name, alias, returnValue.getStrRef(), returnType.getStrRef());
}
};
%rename ("$ignore", fullname=1) "MyClass::method1";
%rename ("$ignore", fullname=1) "MyClass::method2";
%include "MyClass.h"
所以我想知道,从性能的角度来看,witch 更好,结构解决方案(通过 Flexo),通过 Flexo 的字符串数组或这个指针(就像只有一个成员的结构。