如何使用 SWIG/Python 访问只有指针 typedef 的结构的值
How to access value of struct that only has pointer typedef with SWIG/Python
我正在为带有 DLL 和 header 的现有代码库创建一个 Python 包装器。我正在使用 SWIG。
代码库有多个结构指针定义,如下所示:
typedef struct session* session_t;
在此示例中,session
未在其他任何地方定义。 DLL 中的所有其他函数都将 session_t
作为输入。如果我尝试在 SWIG 生成的代码中的任何地方引用 session
,我会收到未定义 session
的编译错误。我需要一种方法来访问 Python 代码中 session_t
的值。
我试过使用 cpointer.i 和 pointer_functions 宏,但这不起作用,因为它假定输入类型不是指针。
我想如果我可以重新定义结构:
typedef struct Session {} session, *session_t;
这可行,但我找不到使用 SWIG 执行此操作的方法。
如果 SWIG 的唯一定义是一个 typdef 结构指针,是否有办法访问它的值?
编辑:可能的解决方法是 SWIG %ignore
指令。或许可以忽略原来的 struct def 并在 .i 文件中替换它。
已解决(大概):我将 Mark Tolonen 的回答标记为正确,因为它包含很多有用的相关信息。我试图包装的 API 有很多已删除的构造函数和行为锁定了它的使用方式。我最终在它自己的命名空间中编写了一个 C++ 包装器,然后告诉 Swig 忽略除我的命名空间之外的所有内容。然后我只使用标准或我自己的类型来与 Swig/Python 交互。
SWIG 非常适合不透明类型。这是一个完整的示例,其中我提供了使用不透明 typedef 的 test.dll
的源代码。该结构仅在 .c
文件中定义,SWIG 不知道该定义。如果您仍然遇到问题,请使用可重现的示例更新您的问题。我怀疑您在某些类型映射中使用了 session
而不是 session_t
,但是没有可重现的示例我只能证明它在没有定义的情况下也能工作。
test.c
#define API_EXPORTS
#include <stdlib.h>
#include "test.h"
struct session {
int a;
};
API session_t alloc(void) {
session_t s = malloc(sizeof(session_t));
if(s)
s->a = 123;
return s;
}
API int get_a(session_t s) {
return s->a;
}
API void release(session_t s) {
free(s);
}
test.h
#ifdef API_EXPORTS
# define API __declspec(dllexport)
#else
# define API __declspec(dllimport)
#endif
typedef struct session* session_t;
API session_t alloc(void);
API int get_a(session_t s);
API void release(session_t session);
test.i
%module test
%{
#include "test.h"
%}
%include <windows.i>
%include "test.h"
测试环节
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> s = test.alloc()
>>> test.get_a(s)
123
>>> test.release(s)
>>>
我正在为带有 DLL 和 header 的现有代码库创建一个 Python 包装器。我正在使用 SWIG。
代码库有多个结构指针定义,如下所示:
typedef struct session* session_t;
在此示例中,session
未在其他任何地方定义。 DLL 中的所有其他函数都将 session_t
作为输入。如果我尝试在 SWIG 生成的代码中的任何地方引用 session
,我会收到未定义 session
的编译错误。我需要一种方法来访问 Python 代码中 session_t
的值。
我试过使用 cpointer.i 和 pointer_functions 宏,但这不起作用,因为它假定输入类型不是指针。
我想如果我可以重新定义结构:
typedef struct Session {} session, *session_t;
这可行,但我找不到使用 SWIG 执行此操作的方法。
如果 SWIG 的唯一定义是一个 typdef 结构指针,是否有办法访问它的值?
编辑:可能的解决方法是 SWIG %ignore
指令。或许可以忽略原来的 struct def 并在 .i 文件中替换它。
已解决(大概):我将 Mark Tolonen 的回答标记为正确,因为它包含很多有用的相关信息。我试图包装的 API 有很多已删除的构造函数和行为锁定了它的使用方式。我最终在它自己的命名空间中编写了一个 C++ 包装器,然后告诉 Swig 忽略除我的命名空间之外的所有内容。然后我只使用标准或我自己的类型来与 Swig/Python 交互。
SWIG 非常适合不透明类型。这是一个完整的示例,其中我提供了使用不透明 typedef 的 test.dll
的源代码。该结构仅在 .c
文件中定义,SWIG 不知道该定义。如果您仍然遇到问题,请使用可重现的示例更新您的问题。我怀疑您在某些类型映射中使用了 session
而不是 session_t
,但是没有可重现的示例我只能证明它在没有定义的情况下也能工作。
test.c
#define API_EXPORTS
#include <stdlib.h>
#include "test.h"
struct session {
int a;
};
API session_t alloc(void) {
session_t s = malloc(sizeof(session_t));
if(s)
s->a = 123;
return s;
}
API int get_a(session_t s) {
return s->a;
}
API void release(session_t s) {
free(s);
}
test.h
#ifdef API_EXPORTS
# define API __declspec(dllexport)
#else
# define API __declspec(dllimport)
#endif
typedef struct session* session_t;
API session_t alloc(void);
API int get_a(session_t s);
API void release(session_t session);
test.i
%module test
%{
#include "test.h"
%}
%include <windows.i>
%include "test.h"
测试环节
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> s = test.alloc()
>>> test.get_a(s)
123
>>> test.release(s)
>>>