首页 > 解决方案 > 使用 SWIG 使用 3rd-Party 驱动程序构建 Python 模块

问题描述

我正在使用提供 Windows 驱动程序 (DLL) 和 C 头文件的第 3 方供应商。我想要做的是使用 SWIG 将头文件重新编译成 Python 模块。

这是我的文件:
- BTICard.i
- BTICard.h
- BTICARD64.dll
- BTICARD64.lib

SWIG 接口源码

%module BTICard
%include <windows.i>
%{
#define SWIG_FILE_WITH_INIT
#include "BTICard.H"
#define BTICardAPI
%}

在 Cygwin 中,我使用了以下命令:

swig -python -py3 BTICard.i

然后生成以下文件:
- BTICard.py
- BTICard_wrap.c

在 Cygwin 中,为 Python 模块编译

gcc -c -fpic BTICARD.H BTICard_wrap.c -I/usr/include/python3.8

现在允许在 Python 中导入 BTICard

import BTICard
import ctypes
BTICarddll = ctypes.WinDLL('BTICARD64')
pRec1553 = SEQRECORD1553() # Doesn't initialize

BTICard.H 包含以下内容:
typedef struct - 用于初始化各种字段结构
enum - 常量声明

根据 SWIG 文档,typedef 结构应该被转换为 Python 类。当我尝试初始化类时,我得到了一个 NameError。我怀疑问题在于我的接口文件无法识别这些类型,因此无法转换它们。

经过进一步调查,我尝试使用 distutils 方法并创建了 setup.py

#!/usr/bin/env python3.8
"""
setup.py file for SWIG
"""
from distutils.core import setup, Extension

example_module = Extension('_BTICard',
    sources=['BTICard_wrap.c', 'BTICard.h'],)

setup (name = 'BTICard',
    version = '0.1',
    author = "TESTER",
    description = """BTICard API""",
    ext_modules = [example_module],
    py_modules = ["BTICard"],
    )

要构建包:

$ python3.8 setup.py build_ext --inplace
running build_ext
building '_BTICard' extension
error: unknown file type '.h' (from 'BTICard.h')

这里有什么问题?

从 gcc 创建对象后,有没有办法可以访问 Python 源文件?

我要做的就是验证一个似乎有问题的单独的 Python Wrapper(这是一个完全独立的主题)。有没有另一种方法来创建这个 Python 模块?

标签: pythonoopvisual-c++ctypesswig

解决方案


.i文件不包括要导出的接口。它应该看起来像:

%module BTICard

%{
#include "BTICard.H"    // this just makes the interface available to the wrapper.
%}

%include <windows.i>
%include "BTICard.h"    // This wraps the interface defined in the header.

setup.py了解 SWIG 接口,因此.i直接将文件作为源包含在内。标头包含在来源中,并且未列为来源。您可能需要其他选择,但这应该让您走上正轨。您可能需要 DLL 导出库 ( BTICard.lib) 并且还需要链接到该库:

example_module = Extension('_BTICard',
    sources=['BTICard.i'],
    libraries=['BTICard.lib'])

推荐阅读