如何在VS2010中使用SWIG?

5 投票
2 回答
6971 浏览
提问于 2025-04-16 17:28

大家好,

我正在尝试把我在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文件上?

抱歉解释得这么长,但我有点迷茫,所以决定把所有情况都说清楚。

2 个回答

0

看起来在ou_thread.h文件里缺少了一些#include的引用。

而且,出现“'class'类型重新定义”的错误,可能是因为你在ou_thread.h里没有类似下面的内容:

#ifndef __ou_thread_h__
#define __ou_thread_h__

// your stuff, classes, etc.

#endif

这只是个猜测……

11

好的,我在使用swig和VS2010时没有遇到问题……

在你的情况下,看起来你更可能是链接方面出了问题。除了检查库文件外,别忘了检查你链接的库是32位还是64位。尽量将所有链接设置为x86目标,这样更安全。不要使用AnyCpu


如何在VS2010中使用SWIG。

假设你想生成mylib.py,所以你创建了一些SWIG接口文件,其中mylib.i是“主”文件。我假设你已经有一个包含C++类的解决方案和项目。

(1) 首先为SWIG接口创建一个C++项目。使用Visual C++->类库项目,这样会创建一个C++ DLL的框架。我把所有的.i文件放在这里,并设置Visual Studio将.i文件高亮显示为.h文件,这样更方便。

(1.1) 将mylib_wrap.cxx文件添加到项目中(如果SWIG还没有生成这个文件,可以先创建一个空文件)。

(2)
a) 右键点击mylib.i,选择属性。
b) 将项目类型设置为“自定义生成工具”。
在自定义生成步骤窗口中:
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

Custom build window

(3) 进入这个项目的属性:

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

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

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

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

f) C/C++ -> 预编译头: 关闭预编译头,设置为**不使用预编译头**,并在之后删除stdafx文件。

g) 常规选项卡。只需检查以下设置:
配置类型 = 动态库 (.dll)
字符集 = 使用Unicode字符集
公共语言运行时支持 = 不支持公共语言运行时

这样就可以编译了。

附言:别忘了在你的系统中设置%PYTHON_INCLUDE%和%PYTHON_LIB%变量。

撰写回答