【问题标题】:SWIG an SDK to PythonSWIG 将 SDK 转换为 Python
【发布时间】:2016-01-28 19:42:54
【问题描述】:

我是 SWIG 的新手,所以我完全没有这方面的经验,但我真的很想使用 Riftek LASER (https://riftek.com/media/rit/SDK/RFDevice_SDK.zip) 的 SDK。

SDK 本身包含一些头文件、dll 和 def 文件。到目前为止,我已经编写了以下 SWIG 文件:

/* rfdevice.i */
%module rfdevice
%{
#include <windows.i>
#include <typemaps.i>
#include "include/RF625Device.h"
#include "include/RF625Device_Legacy.h"
#include "include/RFDevice.h"
#include "include/RFEthernetDetector.h"
#include "include/RFEthernetDevice.h"
#include "include/RFQDPMotorDevice.h"
#include "include/RFSerialDevice.h"
#include "include/RFString.h"
#include "include/RFTypeDefs.h"
#include "include/serial.h"
%}
%include <windows.i>
%include <typemaps.i>

%apply void *INPUT {void *lpResultBuffer};
%apply float *OUTPUT {float *lpPointsBuffer};
%apply USHORT *OUTPUT {USHORT *lpCount};

%include "include/RFString.h"
%include "include/serial.h"
namespace RFDevice {
    %include "include/RFTypeDefs.h"
    %include "include/RFEthernetDetector.h"
    %include "include/RFDevice.h"
    %include "include/RFEthernetDevice.h"
    %include "include/RFQDPMotorDevice.h"
    %include "include/RFSerialDevice.h"
    %include "include/RF625Device_Legacy.h"
    %include "include/RF625Device.h"
}

我可以生成 rfdevice_wrap.c 文件,但我无法编译它,因为我从编译器中得到了很多未定义的引用。

我的问题是: - 我必须以某种方式在 i 文件中包含 dll 或 def 文件吗? - 是否有更快/更简单的方法让 SDK 与 Python 一起工作?

我正在使用 g++ 在 Windows 7 64 位下使用 MinGW 进行编译。


到目前为止,我设法确定了我真正的问题。我根据当前状态修改了问题。

其中一个标头中有如下函数定义:

USHORT ConvertResultToPoints(void IN *lpResultBuffer, float OUT *lpPointsBuffer, USHORT OUT *lpCount, USHORT *lpMeasureCnt = NULL, USHORT *lpPacketCnt = NULL, BOOL bChecksumCheck = FALSE);

这里的“IN”和“OUT”给 SWIG 带来了一些麻烦。我不断收到以下编译器错误:

include\RF625Device_Legacy.h(259): Error: Syntax error in input(3).

在参数处理下的 SWIG 文档中,有可能解决该问题。我已经将它包含在 i 文件中,但我不断收到编译器错误。

【问题讨论】:

  • 您应该在此处包含来自编译器/链接器的错误消息,请参阅minimal reproducible example
  • 为什么要用 g++ 编译 *.c 文件?
  • 无法在i(接口)文件中包含dll/def文件,但必须在编译代码时包含它们
  • 感谢V大师的回答。 Alexander:SDK 中不包含 *.c 文件。只有 *.h 文件。当我查看文件时,语法看起来更像 C++ 而不是 C。实际上,我使用 g++ 得到的编译器错误比使用 gcc 少。
  • 1) 永远不要使用 #include 包含 .i 文件。这没有任何意义,它们不是 C 或 C++ 2) SWIG 不递归标头,因此必须以正确的顺序包含头文件。 3) 不要在命名空间中包含 .i 文件。您得到的语法错误很可能是由于未知的定义,例如出口申报

标签: python c++ g++ mingw swig


【解决方案1】:

你可以这样开始。我使用 CMake

这是我的 CMakeLists.txt 文件。到目前为止,我可以创建 RFString 对象

cmake_minimum_required(VERSION 2.8.9)

find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})

find_package(PythonLibs REQUIRED)

include_directories(${PYTHON_INCLUDE_PATH})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

set_source_files_properties(RFDevice_SDK.i PROPERTIES CPLUSPLUS ON)

set(DEPS_PREFIX ${CMAKE_SOURCE_DIR}/linux)

link_directories(${DEPS_PREFIX})

set(RFDEVICE_LIBS_NAMES RFDevice3)

foreach(lib ${RFDEVICE_LIBS_NAMES})
  find_library(
    ${lib}_LIB
    NAMES ${lib}
    PATHS ${DEPS_PREFIX}
    PATH_SUFFIXES i386 x86_64
  )
  set(RFDEVICE_LIBS ${RFDEVICE_LIBS} ${${lib}_LIB})
endforeach()

message(${RFDEVICE_LIBS})

set(swig_rfdevice_sdk_HEADERS
  ./include/linuxTypeDefs.h
  ./include/RFString.h
)

set(swig_rfdevice_sdk_SOURCES
)

swig_add_module(swig_rfdevice_sdk python RFDevice_SDK.i ${swig_rfdevice_sdk_HEADERS} ${swig_rfdevice_sdk_SOURCES})

swig_link_libraries(swig_rfdevice_sdk ${RFDEVICE_LIBS} ${PYTHON_LIBRARIES})

这是.o文件

%module(docstring="This is a Python wrapper for RFDevice3") swig_rfdevice_sdk
#pragma SWIG nowarn=320
%{

  #define SWIG_FILE_WITH_INIT
  // Try to ignore cast between pointer-to-function and pointer-to-object
  #include "stdint.h"
  #include "linuxTypeDefs.h"
  #include "RFString.h"
%}

#ifdef _SWIG_WIN32
%include "windows.i"
#endif

%include "carrays.i"
%array_class(char, charArrayClass);
%array_functions(char, charArray);

// Individual modules
%include "linuxTypeDefs.h"
%include "RFString.h"

我必须安装旧版本的 glibc++ 才能使其工作。或者,您可以链接到旧版本的 glibc++。

【讨论】:

  • 判断接口是如何创建的,我会使用 ctypes 代替,并在 Python 中创建具有相同二进制布局的结构并简单地调用它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多