gpt4 book ai didi

python - SWIG void * 参数

转载 作者:太空宇宙 更新时间:2023-11-04 02:55:27 25 4
gpt4 key购买 nike

我的 swig .i 文件中有两个结构(实际上来自第三方库)遵循以下形式:

typedef struct MY_STRUCT {
void* pParameter;
unsigned long pLen;
} MY_STRUCT;
%extend MY_STRUCT
{
MY_STRUCT()
{
MY_STRUCT *m= new MY_STRUCT();
m->pParameter = NULL;
m->pLen = 0;
return m;
}
}

typedef struct ANOTHER_STRUCT {
char * another;
unsigned long len;
} ANOTHER_STRUCT;
%extend ANOTHER_STRUCT
{
ANOTHER_STRUCT()
{
ANOTHER_STRUCT *p= new ANOTHER_STRUCT();
p->another = NULL;
p->len = 0;
return p;
}
unsigned long __len__()
{
return sizeof(ANOTHER_STRUCT);
}
}

MY_STRUCT 中的 pParameter 是一个 void *,因为它可以是一个 char * 或一个指向结构(例如 ANOTHER_STRUCT)的指针。使用 %typemap(in) void* = char*; 仅处理 char * 映射很简单,但任何使用结构的尝试都会失败。这是我希望在 Python 中看到的内容:

s = MY_STRUCT()
another = ANOTHER_STRUCT()
s.pParameter = another # this should pass the struct pointer
s.pParameter = "some string" # or a char pointer if this is provided

这可能吗?如果不是,我是否需要声明一些辅助函数来分配指针值?

最佳答案

您可以使用 SWIG 执行此操作。你最终会写一个 fairly large if选择如何处理 Python 输入,具体取决于您要处理的类型数量。这是您需要的两个类型映射的完整示例:

%module test

%typemap(in) void* pParameter (int res=0, void *other_struct=NULL) %{
int len;
res = SWIG_ConvertPtr($input, &other_struct, $descriptor(struct ANOTHER_STRUCT*), 0);
if (SWIG_IsOK(res)) {
fprintf(stderr, "struct\n");
$1 = reinterpret_cast< ANOTHER_STRUCT * >(argp1);
len = sizeof(ANOTHER_STRUCT);
}
else if (PyString_Check($input)) {
$1 = PyString_AsString($input);
len = strlen((const char*)$1);
fprintf(stderr, "string\n");
}
//else if (...) {
//}
else {
SWIG_exception_fail(SWIG_TypeError, "some more details, see special typemap variables docs for ideas");
}
%}

%typemap(memberin) void* pParameter %{
$1 = $input; //fobar $self
$self->pLen = len;
%}

%inline %{
typedef struct MY_STRUCT {
void* pParameter;
unsigned long pLen;
} MY_STRUCT;

typedef struct ANOTHER_STRUCT {
} ANOTHER_STRUCT;
%}

%extend MY_STRUCT
{
MY_STRUCT()
{
MY_STRUCT *m= new MY_STRUCT;
m->pParameter = NULL;
m->pLen = 0;
return m;
}
}

此处 in 类型映射采用 PyObject 并确定如何处理它。它还将长度保存到局部变量中。

memberin 类型映射使用它来适本地设置 void* 和长度。

您可能需要考虑使 pLen 不可变(参见:%immutable),这样人们就不能随意更改该指针。您还需要仔细考虑像这样的类型映射的内存所有权语义,以避免泄漏或双重释放。

关于python - SWIG void * 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18109245/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com