2017-10-20 1 views
0

Ich habe Probleme mit swig und Char ** als Zeiger auf eine Variable char * (nicht als eine Liste von char * !!!). Ich konnte keinen Weg finden, den Zeiger auf ein char * zu legen.swig char ** als Zeiger auf ein char *

Ziel ist es, das Ergebnis der Verkettung in das char * zu schreiben, auf das der Zeiger verweist.

Das folgende ist mein Code:

Datei 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); 
} 

Datei pointers.h

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

Datei 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); 

Datei-Setup .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"], 
    ) 

Schließlich ist die Python-Haupt:

import pointers 

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

Und alle sind mit Terminal-Befehle zusammengestellt:

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

Aber der Compiler Rückkehr Fehler:

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 

Irgendwelche hilft?

[UPDATE ZUR FRAGE]

Wie @MarkTolonen schlug ich versucht, die pointers.i Datei auf folgende Weise zu ändern:

Neue Datei 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" 

Kompilieren mit:

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 

Und dann habe ich den Fehler:

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); 

Es funktioniert auf diesem Windows-Betriebssystem, aber nicht auf meinem Ubuntu. Kann jemand sagen, wie man damit umgeht? Ich weiß wirklich nicht, wie mein Zeigerproblem gelöst wird.

+0

wo pointers_wrap.cxx kommen? > 3k Zeilen in einer einzigen Datei macht mich schwindelig, auch ohne die Datei zu sehen – user463035818

+0

yeah, es wird erstellt, die Datei setup.py. Es ist die automatisch erzeugte Datei, um die Wrapper-Datei zu erstellen. Und es wird bei der Erstellung des Swig-Moduls benötigt. – lorsp000

Antwort

0

Von der SWIG 3.0-Dokumentation, in der Nähe von Ende §9.2.1 cpointer.i:

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

So werden Sie zu typemaps greifen müssen. Unten ist ein Beispiel:

pointers.cpp

ich leicht Ihre Quelle ändern musste. Ein char** Argument sollte die zugewiesenen Zeiger zurückgeben, und es ist nicht frei:

#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); 
} 

Zeiger.h

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

pointers.i

Diese Version der swig Datei deklariert die typemaps die char** Ausgabeargument zu behandeln.

%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) 

Ausgabe

Hello World!

+0

danke! Aber beim Kompilieren des Codes habe ich einige Fehler bekommen, die in der Funktion 'PyObject * _wrap_conc (PyObject *, PyObject *)' 'jump to label 'fail' beziehen und eine Anmerkung:' kreuzt die Initialisierung von' _object * obj'' on 'auto obj ='. Weißt du warum? – lorsp000

+0

@ lorsp000 Ihr C++ - Compiler ist alt. Ändern Sie auto in den Rückgabetyp von PyUnicodeFromString. Ich denke es ist PyObject *. –

+0

Ich habe versucht, den Rückgabetyp zu ändern, funktioniert aber immer noch nicht. Auf der anderen Seite habe ich eine g ++ 6.3.0 Version, ist es zu alt für PyUnicodeFromString? – lorsp000