2017-10-20 28 views
0

変数char(char * !!!のリストではありません)へのポインタとしてswigとchar **に問題があります。私はchar *へのポインタをラップする方法を見つけることができませんでした。swig char ** charへのポインタとして*

目的は、連結の結果をポインタによって参照されるchar *に書き出すことです。

次は私のコードです:

ファイルpointers.cpp:

#include "pointers.h" 
#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 

void conc(char *str1, char *str2, char **res){ 
    char *aux = (char *)malloc(strlen(str1)+strlen(str2)+1); 
    strcpy(aux,str1); 
    strcat(aux,str2); 
    strcpy(*res,aux); 
    free(aux); 
} 

ファイルpointers.h

void conc(char *str1, char *str2, char **res) 

ファイルpointers.i

%module pointers 
%{ 
#define SWIG_FILE_WITH_INIT 
#include "pointers.h" 
%} 

%include "typemaps.i" 
%include "cpointer.i" 
%include "cstring.i" 

%pointer_functions(char *, charp); 
extern void conc(char *str1, char *str2, char **res); 

ファイルのセットアップ.py:

from distutils.core import setup, Extension 


pointers_module = Extension('_pointers', 
         sources=['pointers_wrap.cxx', 'pointers.cpp'], 
         ) 

setup (name = 'pointers', 
    version = '0.1', 
    author  = "SWIG Docs", 
    description = """Simple swig example from docs""", 
    ext_modules = [pointers_module], 
    py_modules = ["pointers"], 
    ) 

最後に、メインのpython:

swig -c++ -python pointers.i 
python setup.py build_ext --inplace 

しかし、コンパイラのリターンエラー:

pointers_wrap.cxx: In function ‘char** copy_charp(char*)’: 
pointers_wrap.cxx:3124:58: error: invalid static_cast from type ‘char*’ to    
type ‘const char*&’ return (new char *(static_cast< const char *& >(value))); 
                     ^
error: command 'gcc' failed with exit status 1 

import pointers 

result = new_charp() 
pointers.conc("Hello ","World!", result); 
print(result) 
delete_charp(result) 

そして、それらのすべては、端末のコマンドでコンパイルされていますどんな助け?

新しいファイルpointers.i:

%module pointers 

%{ 
#include "pointers.h" 
%} 

// This input typemap declares that char** requires no input parameter. 
// Instead, the address of a local char* is used to call the function. 
%typemap(in,numinputs=0) char** (char* tmp) %{ 
    $1 = &tmp; 
%} 

// After the function is called, the char** parameter contains a malloc'ed char* pointer. 
// Construct a Python Unicode object (I'm using Python 3) and append it to 
// any existing return value for the wrapper. 
%typemap(argout) char** %{ 
    PyObject *obj = PyUnicode_FromString(*$1); 
    $result = SWIG_Python_AppendOutput($result,obj); 
%} 

// The malloc'ed pointer is no longer needed, so make sure it is freed. 
%typemap(freearg) char** %{ 
    free(*$1); 
%} 

// Now that the typemap exists, let swig wrap the header. 
%include "pointers.h" 

@MarkTolonenによって示唆されるように

[QUESTION TO UPDATE]は

は、私は次のようにpointers.iファイルを変更しようとしましたコンパイルすると:

swig -c++ -python pointers.i 
g++ --std=c++11 -fPIC -c pointers.cpp 
g++ --std=c++11 -fPIC -c pointers_wrap.cxx -I/usr/local/include/python3.6m 

次に、エラーが表示されます。

In function ‘PyObject* _wrap_conc(PyObject*, PyObject*):` 
pointers_wrap.cxx:3618:1: error: jump to label ‘fail’ [-fpermissive] 
fail: 
pointers_wrap.cxx:1222:49: note: from here 
#define SWIG_fail     goto fail 

pointers_wrap.cxx:2999:68: note: in expansion of macro ‘SWIG_fail’ 
#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) 
pointers_wrap.cxx:3603:5: note: in expansion of macro ‘SWIG_exception_fail’ 
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "conc" "', argument " "2"" of type '" "char *""'"); 

pointers_wrap.cxx:3609:8: note: crosses initialization of ‘_object* obj’ 
auto obj = PyUnicode_FromString(*arg3); 
pointers_wrap.cxx:3618:1: error: jump to label ‘fail’ [-fpermissive] 
fail: 

pointers_wrap.cxx:1222:49: note: from here 
#define SWIG_fail      goto fail 
pointers_wrap.cxx:2999:68: note: in expansion of macro ‘SWIG_fail’ 
#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) 
pointers_wrap.cxx:3598:5: note: in expansion of macro ‘SWIG_exception_fail’ 
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "conc" "', argument " "1"" of type '" "char *""'"); 

pointers_wrap.cxx:3609:8: note: crosses initialization of ‘_object* obj’ 
auto obj = PyUnicode_FromString(*arg3); 

pointers_wrap.cxx:3618:1: error: jump to label ‘fail’ [-fpermissive] 
fail: 
pointers_wrap.cxx:1222:49: note: from here 
#define SWIG_fail     goto fail 
pointers_wrap.cxx:3595:62: note: in expansion of macro ‘SWIG_fail’ 
if (!PyArg_ParseTuple(args,(char *)"OO:conc",&obj0,&obj1)) SWIG_fail; 
pointers_wrap.cxx:3609:8: note: crosses initialization of ‘_object* obj’ 
auto obj = PyUnicode_FromString(*arg3); 

このWindows OSでは動作しますが、私のubuntuでは動作しません。誰もそれに対処する方法を教えてもらえますか?私は実際に私のポインタの問題を解決する方法を知らない。

+0

? > 3k行で1つのファイルを見ると、ファイルが表示されなくてもわかりにくくなります – user463035818

+0

ええ、setup.pyというファイルを実行して作成されています。これは、ラッパーファイルを構築するswigによる自動作成ファイルです。そしてそれはswigモジュールの作成に必要です。 – lorsp000

答えて

0

§9.2.1 cpointer.iの終わり近くにSWIG 3.0ドキュメント、投稿者:

Note: None of these macros can be used to safely work with strings (char * or char **).

だから、タイプマップに頼る必要があります。

pointers.cpp

私は少しあなたのソースを変更する必要がありました。以下は一例です。 char**引数は、割り当てられたポインタを返し、それを解放しないでください。

#include <string.h> 
#include <stdlib.h> 
#include "pointers.h" 

void conc(char *str1, char *str2, char **res){ 
    *res = (char *)malloc(strlen(str1)+strlen(str2)+1); 
    strcpy(*res,str1); 
    strcat(*res,str2); 
} 

ポインタを。時間

void conc(char *str1, char *str2, char **res); 

pointers.i

SWIGファイルのこのバージョンは、char**出力引数を処理するためにタイプマップを宣言します。

%module pointers 

%{ 
#include "pointers.h" 
%} 

// This input typemap declares that char** requires no input parameter. 
// Instead, the address of a local char* is used to call the function. 
%typemap(in,numinputs=0) char** (char* tmp) %{ 
    $1 = &tmp; 
%} 

// After the function is called, the char** parameter contains a malloc'ed char* pointer. 
// Construct a Python Unicode object (I'm using Python 3) and append it to 
// any existing return value for the wrapper. 
%typemap(argout) char** (PyObject* obj) %{ 
    obj = PyUnicode_FromString(*$1); 
    $result = SWIG_Python_AppendOutput($result,obj); 
%} 

// The malloc'ed pointer is no longer needed, so make sure it is freed. 
%typemap(freearg) char** %{ 
    free(*$1); 
%} 

// Now that the typemap exists, let swig wrap the header. 
%include "pointers.h" 

test.py

import pointers 
result = pointers.conc('Hello ','World!'); 
print(result) 

出力pointers_wrap.cxxから来ている

Hello World!

+0

ありがとう!しかし、あなたのコードをコンパイルすると、私はいくつかのエラーがあり、 'PyObject * _wrap_conc(PyObject *、PyObject *)'関数で '' label 'にジャンプ' 'し、 '' _object * obj' ' 'auto obj ='です。なぜあなたは知っていますか? – lorsp000

+0

@ lorsp000あなたのC++コンパイラは古いです。 autoをPyUnicodeFromStringの戻り値の型に変更します。 PyObject *だと思います。 –

+0

戻り値の型を変更しようとしましたが、それでも動作しません。一方、私はg ++ 6.3.0のバージョンを持っていますが、それはPyUnicodeFromStringには古すぎますか? – lorsp000

関連する問題