如何在 VS2010 中 SWIG?

Posted

技术标签:

【中文标题】如何在 VS2010 中 SWIG?【英文标题】:How to SWIG in VS2010? 【发布时间】:2011-05-11 18:53:43 【问题描述】:

大家好, 我正在尝试将我在 VS2010 (c++) 中制作的多文件项目 SWIG 到 python。我已经成功地链接了 Python26.lib 文件,并让 SWIG 为我的主 .cpp 文件生成了一个包装器 .cpp 文件。我已经设置我的代码来构建一个扩展名为 .pyd 的 .dll。

这是我目前拥有的 .i 文件:

%module HiveGPS

%
#include "ou_thread.h"
#include "HiveGPS.h"
%


%include ou_thread.h
%include HiveGPS.h

我已经获得了 .py 和 .pyc 文件。现在,根据我的理解,为了运行我的 .py 文件,我需要将它链接到我的 .pyd 文件,但是当我尝试使用 VS2010 使用上面列出的设置构建我的项目时,它抱怨我的 Thread 类正在使用:

1>------ Build started: Project: HiveGPS, Configuration: Release Win32 ------
1>Build started 5/11/2011 1:41:30 PM.
1>InitializeBuildStatus:
1>  Touching "Release\HiveGPS.unsuccessfulbuild".
1>ClCompile:
1>  HiveGPS_wrap.cpp
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(57): error C2146: syntax error : missing ';' before identifier 'm_strName'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(57): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(57): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(64): error C2146: syntax error : missing ';' before identifier 'getName'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(64): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(64): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(64): warning C4183: 'getName': missing return type; assumed to be a member function returning 'int'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(98): error C2146: syntax error : missing ';' before identifier 'm_strName'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(98): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(98): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(104): error C2146: syntax error : missing ';' before identifier 'getName'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(104): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(104): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(104): warning C4183: 'getName': missing return type; assumed to be a member function returning 'int'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(115): error C2146: syntax error : missing ';' before identifier 'msg'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(115): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(115): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(118): error C2146: syntax error : missing ';' before identifier 'getMessage'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(118): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(118): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(118): warning C4183: 'getMessage': missing return type; assumed to be a member function returning 'int'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(51): error C2011: 'openutils::Thread' : 'class' type redefinition
1>          c:\users\*\desktop\hivegps\hivegps\ou_thread.h(51) : see declaration of 'openutils::Thread'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(93): error C2011: 'openutils::Mutex' : 'class' type redefinition
1>          c:\users\*\desktop\hivegps\hivegps\ou_thread.h(93) : see declaration of 'openutils::Mutex'
1>c:\users\*\desktop\hivegps\hivegps\ou_thread.h(113): error C2011: 'openutils::ThreadException' : 'class' type redefinition
1>          c:\users\*\desktop\hivegps\hivegps\ou_thread.h(113) : see declaration of 'openutils::ThreadException'
1>c:\users\*\desktop\hivegps\hivegps\HiveGPS.h(29): error C2504: 'openutils::Thread' : base class undefined
1>c:\users\*\desktop\hivegps\hivegps\HiveGPS.h(53): error C2079: 'HiveGPS::readWriteMutex' uses undefined class 'openutils::Mutex'
1>HiveGPS_wrap.cpp(3086): error C2027: use of undefined type 'openutils::Thread'
1>          c:\users\*\desktop\hivegps\hivegps\ou_thread.h(51) : see declaration of 'openutils::Thread'
1>HiveGPS_wrap.cpp(3086): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.10
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

所有这些错误(减去最后一个)基本上都是在说 String 类以某种方式实现,它是否与 Python 对 String 类的定义冲突?最后一个错误是抱怨 Thread 类,会不会是同一个问题?

所有这些都说: 有人能告诉我我做错了什么吗,或者更好的是,给我指出如何为 VS2010 执行此操作的教程(SWIG 网站适用于 2008 年)。

如果不能这样做,我可以将我生成的 .py 文件以某种方式链接到 .dll 文件吗?

对不起,解释太长了,但我对这个有点迷茫,所以我决定解释一切。

【问题讨论】:

它可以是任何东西。 SWIG 支持相当多,但在某些构造方面需要帮助。如果没有看到头文件或您如何编译生成的 SWIG 包装器,很难确定哪里出了问题。 如果使用的字符串是std::string,见swig.org/Doc1.3/Library.html 【参考方案1】:

好的,我正在使用 swig 和 VS2010 没有问题...

在您的情况下,您的链接看起来更像是有问题。除了检查库之外,不要忘记检查您正在链接的 32-64 位库。尝试将所有链接作为 x86 目标作为故障安全。并且不要使用 AnyCpu


如何在VS2010下使用SWIG。

让我们定义您想要获取 mylib.py,因此您创建了一些 SWIG 接口文件,其中 mylib.i 作为“主”文件。我假设您已经有了一个带有 C++ 类的项目的解决方案。

(1) 首先为 SWIG 接口创建 C++ 项目。使用应创建 C++ DLL 存根的 Visual C++-> 类库项目。我把所有 .i 文件放在那里。并将视觉工作室设置为将 .i 突出显示为 .h - 这很方便。

(1.1) 将 mylib_wrap.cxx 文件添加到项目中(创建空文件,而 swig 尚未生成)

(2) a) 在 mylib.i 上按右键,选择属性。 b) 将 ItemType 设置为“自定义构建工具”。 在自定义构建步骤窗口中: c) 命令行字段应该是这样的:

echo In order to function correctly, please ensure the following environment variables are
correctly set: 
echo PYTHON_INCLUDE: %PYTHON_INCLUDE% 
echo PYTHON_LIB: %PYTHON_LIB% 
echo on 
C:\swig\swig.exe -c++ -python %(FullPath) 

将 C:\swig\swig.exe 更改为 SWIG 的路径

d) 在输出字段中:

$(InputName)_wrap.cxx

(3) 转到此项目属性:

a) C++ 选项卡 -> 其他包含目录 添加 $(PYTHON_INCLUDE); ...

c) 链接器 -> 输出文件您需要的路径\_mylib.pyd

d) 链接器 -> 启用增量链接 设置为否 (/INCREMENTAL:NO)

e) 链接器 -> 输入 -> 附加依赖项 添加 $(PYTHON_LIB);...

f) C/C++ -> 预编译头文件: 关闭预编译头文件,设置 **Not Using Precompiled Headers* 并在之后删除 stdafx 文件

g) 常规标签。只需检查这些是否已设置: 配置类型 = 动态库 (.dll) 字符集 = 使用 Unicode 字符集 公共语言运行时支持 = 没有公共语言运行时支持

它编译。

附:并且不要忘记在您的系统中设置 %PYTHON_INCLUDE% 和 %PYTHON_LIB% 变量。

【讨论】:

输出的 .cxx 文件是否必须包含在项目中?【参考方案2】:

ou_thread.h 中似乎缺少一些#include。

此外,“'class'类型重新定义”可以表明您没有类似的东西

#ifndef __ou_thread_h__
#define __ou_thread_h__

// your stuff, classes, etc.

#endif

在您的 ou_thread.h 中

这是一个猜测......

【讨论】:

以上是关于如何在 VS2010 中 SWIG?的主要内容,如果未能解决你的问题,请参考以下文章

如何在带有 Swig 的 Python 中使用 float **?

如何在 swig 接口文件中集成可以抛出 MyException 的 C++ 函数

如何将 C# 字符串 [] 编组(理想情况下在 SWIG 中)到 C++ 字符串*?

如何使用 SWIG 从 C++ 调用 Java?

SWIG 在 Windows 平台上的调试

为 Python 或 SWIG 模块创建编译 C-dll,如何继续?