关于char*
全局 char* 变量
SWIG 使用malloc() 或者 new 来给新值分配内存。比如如下形式的一个变量:
char *foo ;
SWIG 生成如下代码:
/* C mode */
void foo_set(char *value) {
if (foo) free(foo);
foo = (char *) malloc(strlen(value)+1);
strcpy(foo,value);
}
/* C++ mode. When -c++ option is used */
void foo_set(char *value) {
if (foo) delete [] foo;
foo = new char[strlen(value)+1];
strcpy(foo,value);
}
如果这不是你希望的行为,比如这是个只读变量,可以用 %immutable 标识。或者你可以写个自己的辅助赋值函数,比如:
%inline %{
void set_foo(char *value) {
strncpy(foo,value, 50);
}
%}
注意:如果你写了如上形式的函数,你就必须在目标语言里调用这个函数来赋值(这使得它在目标语言中看上去不像个变量),比如在Python 中你必须这样写:
>>> set_foo("Hello World")
Setting const char* variable may leak memory
SWIG 这个警告信息,通常是由C 里的const char* 变量引起的。SWIG缺省照样会给该变量生成 setting 和 getting 函数,但是并不是释放前一次的内容(结果就是可能有内存泄漏)。
一种常犯的错误
在C/C++里常有如下的定义:
char *VERSION = “1.0”;
SWIG缺省生成的代码(参见上文),SWIG会用free() 或 delete 释放内存,这将导致保护错。解决办法:
将变量标记为read-only. (%immutable), 写一个typemap (见Document 第6章),或者写一个特殊的set function.(如上)。另外也可以把变量定义成字符数组:
char VERSION[64] = "1.0";
为C struct 添加 member function
假设有如下C头文件:
/* file : vector.h */
...
typedef struct Vector {
double x,y,z;
} Vector;可以通过SWIG的 interface 让 Vector 看上去像个类。
// file : vector.i
%module mymodule
%{
#include "vector.h"
%}
%include "vector.h" // Just grab original C header file
%extend Vector { // Attach these functions to struct Vector
Vector(double x, double y, double z) {
Vector *v;
v = (Vector *) malloc(sizeof(Vector));
v->x = x;
v->y = y;
v->z = z;
return v;
}
~Vector() {
free($self);
}
double magnitude() {
return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z);
}
void print() {
printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z);
}
};
%extend 指令也可以用在struct定义之内:
// file : vector.i
%module mymodule
%{
#include "vector.h"
%}
typedef struct Vector {
double x,y,z;
%extend {
Vector(double x, double y, double z) { ... }
~Vector() { ... }
...
}
} Vector;
%extend 指令也可以直接引用C里的函数,只要这些函数名按照约定的命名规范:
/* File : vector.c */
/* Vector methods */
#include "vector.h"
Vector *new_Vector(double x, double y, double z) {
Vector *v;
v = (Vector *) malloc(sizeof(Vector));
v->x = x;
v->y = y;
v->z = z;
return v;
}
void delete_Vector(Vector *v) {
free(v);
}
double Vector_magnitude(Vector *v) {
return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}
// File : vector.i
// Interface file
%module mymodule
%{
#include "vector.h"
%}
typedef struct Vector {
double x,y,z;
%extend {
Vector(int,int,int); // This calls new_Vector()
~Vector(); // This calls delete_Vector()
double magnitude(); // This will call Vector_magnitude()
...
}
} Vector;
这篇博客探讨了在SWIG中使用char*时遇到的问题,包括全局char*变量的内存分配,设置const char*变量可能导致的内存泄漏,以及如何避免常见的错误。还介绍了如何为C结构体添加member function。
&spm=1001.2101.3001.5002&articleId=9349081&d=1&t=3&u=623fd3dc19fe460c8309ab6959db9866)
653

被折叠的 条评论
为什么被折叠?



