【发布时间】:2025-12-25 03:00:07
【问题描述】:
背景。我有一个由 C 头文件和一个共享库组成的 API(第三方提供)。我已经设法为构建环境创建了一个 shell 脚本,以及一个简单的 swig 接口文件。我正在尝试使 IPython 环境可以访问此 API,这样我就不必一直编译 C 代码来与利用此 API 进行 I/O 的相关硬件进行通信。
问题。我需要做的第一个函数调用创建一个板句柄(一些任意“对象”,用于 C 端中的所有其他函数调用。该函数接受 void **,假设底层函数可能是 malloc-ing 内存,具有某种内部结构,并允许通过其他一些函数访问此内存。无论如何,由于缺乏对 void * 的支持,我似乎无法从 Python 正确地与此接口并收到 typeError。
带有从底层头文件中提取的 typedef/defines 的违规 C 代码 sn-p 是:
#define WD_PVOID void*
typedef WD_PVOID WD_BOARD;
typedef WD_UINT32 WD_RetCode;
#define WD_EXPORT extern
#define WD_CHAR8 char
#define WD_UINT32 unsigned int
#---------------------------------------
//prototype
WD_EXPORT WD_RetCode wd_CreateBoardHandle( WD_BOARD *pBoardHandle, const WD_CHAR8 *pUrl );
//interpreted prototype
//extern unsigned int wd_CreateBoardHandle( void* *pBoardHandle, const char *pUrl );
第三方提供的示例(用 C 编写)使用该函数(我删除了多余的东西):
int main(int argc, char *argv [])
{
WD_RetCode rc;
Vhdl_Example_Opts cmdOpts = VHDL_EXAMPLE_DEFAULTS;
char urlBoard[VHDL_SHORT_STRING_LENGTH];
WD_BOARD BoardHandle;
sprintf(urlBoard, "/%s/%s/wildstar7/board%d", cmdOpts.hostVal, cmdOpts.boardDomain, cmdOpts.boardSlot);
rc = wd_CreateBoardHandle(&BoardHandle,urlBoard);
}
最后,我淡化的 swig 接口文件(我一直在尝试 swig typedef 和 *OUTPUT,但没有成功):
%module wdapi
%{
#include "wd_linux_pci.h"
#include "wd_types.h"
#include "wd_errors.h"
%}
%import "wd_linux_pci.h"
%import "wd_types.h"
%import "wd_errors.h"
%include <typemaps.i>
WD_EXPORT WD_RetCode wd_CreateBoardHandle( WD_BOARD *pBoardHandle, const WD_CHAR8 *pUrl );
WD_EXPORT WD_RetCode wd_OpenBoard( WD_BOARD BoardHandle );
我希望能够在 python 中这样调用该函数:
rslt,boardHandle = wdapi.wd_CreateBoardHandle("/foo/bar/etc")
如果我可以提供任何其他信息,请告诉我,非常感谢您对解决方案的帮助/指导!我花了几天的时间试图查看发布的其他类似问题。
编辑。我从其他有类似问题的帖子中操作了一些 typedef。我现在可以调用函数并接收 rslt 和 boardHandle 中的值作为对象;但是,似乎 rslt 值是乱码。这是新的 swig 接口文件(对这个问题有什么想法吗?):
%module wdapi
%{
#include "wd_linux_pci.h"
#include "wd_types.h"
#include "wd_errors.h"
%}
%import "wd_linux_pci.h"
%import "wd_types.h"
%import "wd_errors.h"
%include <python/typemaps.i>
%typemap(argout) WD_BOARD *pBoardHandle
{
PyObject *obj = PyCObject_FromVoidPtr( *$1, NULL );
$result = PyTuple_Pack(2, $result, obj);
}
%typemap(in,numinputs=0) WD_BOARD *pBoardHandle (WD_BOARD temp)
{
$1 = &temp;
}
%typemap(in) WD_BOARD {
$1 = PyCObject_AsVoidPtr($input);
}
WD_EXPORT WD_RetCode wd_CreateBoardHandle( WD_BOARD *pBoardHandle, const WD_CHAR8 *pUrl );
WD_EXPORT WD_RetCode wd_OpenBoard( WD_BOARD BoardHandle );
WD_EXPORT WD_RetCode wd_DeleteBoardHandle( WD_BOARD BoardHandle );
WD_EXPORT WD_RetCode wd_IsBoardPresent( const WD_CHAR8 *pUrl, WD_BOOL *OUTPUT );
【问题讨论】: