Input sting for wrapped C++ function doesn't changing SWIG

梦想的初衷 提交于 2020-01-05 03:36:19

问题


I make Python wrapper for C++ library.

mylib.i:

%module mylib
%include <std_string.i>

%{
    #include "mylib.h"

%}
%apply const std::string & {std::string &};
%apply std::string & {std::string &};

int getResult(const std::string& path, std::string& result);

mylib.h:

#pragma once

#include <string>

myEnum {foo=0, bar};
myEnum getResult(const std::string& path, std::string& result);

After generating _mylib.so with following command:

g++ -fPIC -Wall -Wextra -shared mylib_wrap.cxx -o _mylib.so -L. -lmylib -I/usr/include/python2.7/ -lpython2.7

I do next:

LD_LIBRARY_PATH=. python Python 2.7.2 (default, Dec  6 2016, 10:43:39) 
[GCC 4.8.4] on linux4
Type "help", "copyright", "credits" or "license" for more information.
>>> import _mylib
>>> result= ""
>>> x = _mylib.getResult("somePath",result)

After execution of my function, x returns right respond of method. Also I have console output from my function. But result string doesn't changing. If I init result string with "some text", and call my function again, print result return "some text". What I'm doing wrong?


回答1:


The simplest way to get this to work inside your interface is to use %inline to create an overload that returns the result instead:

%module mylib
%include <std_string.i>

%{
    #include "mylib.h"
%}

%inline %{
    int getResult(const std::string& path) {
        std::string temp;
        const int ret = getResult(path, temp);
        if (ret != good) abort(); // TODO exceptions
        return temp;
    }
%}

You don't even need to show SWIG the real version of getResult.

There are other options (e.g. use an input typemap with numinputs=0 and an argout typemap to modify the return value), but they're more complicated and generally less portable to other languages.




回答2:


Doesn't matter how much trickery SWIG does in this case, it can't get around the fact that python strings are immutable - once set, you can't change them.

The SWIG generated code looks vaguely like this:

std::string *arg1 = make a new std::string from path;
std::string *arg2 = make a new std::string from result;
result = (int)getResult((std::string const &)*arg1,*arg2);
resultobj = SWIG_From_int(static_cast< int >(result));
if (SWIG_IsNewObj(res1)) delete arg1;
if (SWIG_IsNewObj(res2)) delete arg2;

Note that it makes a new string from the strings passed in, and then nukes them at the end - after all, strings are immutable.

a lazy solution would be simply returning the json string e.g. an interface of:

std::string getResult(std::string &path)

would have the desired effect.

Now if you want a special return value, it's objects and all that would be entailed in that.



来源:https://stackoverflow.com/questions/40997992/input-sting-for-wrapped-c-function-doesnt-changing-swig

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!