swig char ** 作为指向 char * 的指针
swig char ** as a pointer to a char *
我在使用 swig 和 char ** 作为指向变量 char * 的指针(而不是 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);
文件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"],
)
最后,python main:
import pointers
result = new_charp()
pointers.conc("Hello ","World!", result);
print(result)
delete_charp(result)
而且都是用终端命令编译的:
swig -c++ -python pointers.i
python setup.py build_ext --inplace
但是编译return错误:
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
有帮助吗?
[问题更新]
按照@MarkTolonen 的建议,我尝试按以下方式更改 pointers.i 文件:
新文件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) %{
= &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(*);
$result = SWIG_Python_AppendOutput($result,obj);
%}
// The malloc'ed pointer is no longer needed, so make sure it is freed.
%typemap(freearg) char** %{
free(*);
%}
// Now that the typemap exists, let swig wrap the header.
%include "pointers.h"
编译:
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。任何人都可以告诉如何处理它。我真的不知道如何解决我的指针问题。
来自 SWIG 3.0 文档,接近 §9.2.1 cpointer.i
的末尾:
Note: None of these macros can be used to safely work with strings (char * or char **).
因此您将不得不求助于类型映射。下面是一个例子:
pointers.cpp
我不得不稍微更改一下您的来源。 char**
参数应该 return 分配的指针,而不是释放它:
#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);
}
pointers.h
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) %{
= &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(*);
$result = SWIG_Python_AppendOutput($result,obj);
%}
// The malloc'ed pointer is no longer needed, so make sure it is freed.
%typemap(freearg) char** %{
free(*);
%}
// Now that the typemap exists, let swig wrap the header.
%include "pointers.h"
test.py
import pointers
result = pointers.conc('Hello ','World!');
print(result)
输出
Hello World!
我在使用 swig 和 char ** 作为指向变量 char * 的指针(而不是 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);
文件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"],
)
最后,python main:
import pointers
result = new_charp()
pointers.conc("Hello ","World!", result);
print(result)
delete_charp(result)
而且都是用终端命令编译的:
swig -c++ -python pointers.i
python setup.py build_ext --inplace
但是编译return错误:
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
有帮助吗?
[问题更新]
按照@MarkTolonen 的建议,我尝试按以下方式更改 pointers.i 文件:
新文件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) %{
= &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(*);
$result = SWIG_Python_AppendOutput($result,obj);
%}
// The malloc'ed pointer is no longer needed, so make sure it is freed.
%typemap(freearg) char** %{
free(*);
%}
// Now that the typemap exists, let swig wrap the header.
%include "pointers.h"
编译:
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。任何人都可以告诉如何处理它。我真的不知道如何解决我的指针问题。
来自 SWIG 3.0 文档,接近 §9.2.1 cpointer.i
的末尾:
Note: None of these macros can be used to safely work with strings (char * or char **).
因此您将不得不求助于类型映射。下面是一个例子:
pointers.cpp
我不得不稍微更改一下您的来源。 char**
参数应该 return 分配的指针,而不是释放它:
#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);
}
pointers.h
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) %{
= &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(*);
$result = SWIG_Python_AppendOutput($result,obj);
%}
// The malloc'ed pointer is no longer needed, so make sure it is freed.
%typemap(freearg) char** %{
free(*);
%}
// Now that the typemap exists, let swig wrap the header.
%include "pointers.h"
test.py
import pointers
result = pointers.conc('Hello ','World!');
print(result)
输出
Hello World!