C std :: string como parâmetros de saída em Java com SWIG [duplicado]
Esta questão já tem uma resposta aqui:
SWIG: Como quebrar std :: string & (std :: string passado por referência) 1 respostaEu preciso envolver uma biblioteca C ++ com SWIG para usá-lo com Java.
Já tenho alguns métodos funcionando, mas encontrei uma situação que não sei como resolvê-lo.
Eu tenho um par de métodos como este:
void method1(std::string & name, std::string & result);
bool method2(std::string & name, std::string & alias, std::string & resurnValue, std::string & returnType);
Nota: Na verdade, são métodos membros de uma classe chamada MyClass.
Eu poderia mudar o primeiro método para retornar umstd::string
em vez de servoid
e isso deve funcionar; mas não tenho idéia de como lidar com o segundo método em que os dois últimos parâmetros são parâmetros de saída. Eu vi algumas perguntas arbitrandochar *
Params de saída (Passando vários parâmetros e alocando strings em C usando Swig / Python), mas no meu caso deve ser umstd::string
e a Documentação do SWIG não menciona esta situaçãoinsira a descrição do link aqui. Também eu provavelmente encontro mais métodos retornando 3 ou mais parâmetros de saída, provavelmente com tipos diferentes.
Finalmente, eu tenho um pouco de controle sobre a interface, também estou desenvolvendo uma classe que atua como um ponto de entrada para a biblioteca, mas apenas passa a chamada para a implementação real.
Por exemplo, eu consegui mudar um método comomethod3(std::string & s)
paramethod3(const std::string & s)
, então eu poderia usá-lo de Java com um normalString
.
Portanto, modificar um pouco as assinaturas de métodos é possível, mas se um método nativo retornar n parâmetros de saída, devo retornar todos eles (não consigo criar novos métodos para retornar cada um deles).
Atualizar: Eu estive olhando para a solução dada pelo Flexo e funciona muito bem, no entanto eu estou pensando em fazer uma classe para embrulhar std :: string e usar isso para interagir com strings retornadas, é uma abordagem muito semelhante à segunda solução do Flexo, mas usar esse StringWrapper em vez de usar uma matriz java String, basicamente se parece com isso:
/*
* 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"
Então, eu estou querendo saber, do ponto de vista do desempenho, que a bruxa é melhor, a solução de structs (pelo Flexo), a matriz de strings pelo Flexo ou esse ponteiro (como uma struct com apenas um membro.