如何在VS2010中使用SWIG?
大家好,
我正在尝试把我在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 个回答
看起来在ou_thread.h文件里缺少了一些#include的引用。
而且,出现“'class'类型重新定义”的错误,可能是因为你在ou_thread.h里没有类似下面的内容:
#ifndef __ou_thread_h__
#define __ou_thread_h__
// your stuff, classes, etc.
#endif
这只是个猜测……
好的,我在使用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
(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%变量。