【问题标题】:Get SFML cross-platform typedefs in SWIG在 SWIG 中获取 SFML 跨平台 typedef
【发布时间】:2026-01-25 13:35:01
【问题描述】:

我正在编写一个 C++ 游戏,并将其与 Lua 连接。我为此任务选择的工具是SWIG,因为我想让我的游戏可以用python或其他语言编写。我还使用SFML 1.6 作为多媒体访问的API。该游戏还旨在跨平台编译。我目前正在使用 Xubuntu 11.04 进行项目的第一次尝试。

我已经在我的游戏中封装了 90% 以上的 SFML API,但是当我尝试在我的 Lua 脚本中创建一个新的 sf::Color 对象(以便我可以调用 sf::RenderWindow::Clear(sf::Color) 方法)时,我的 Lua脚本指责这个调用...

renderWindow:Clear( sf.Color( 200, 0, 0 ) ) --Fill the screen with the color.

...试图调用方法sf:Color( Uint8, Uint8, Uint8 );此警告提醒我 SWIG 无法识别 <SFML/Config.hpp> 头文件中定义的跨平台开发的 SFML 特殊 typedef 整数。

现在,在我的 SWIG Config.i 文件中,我可以简单地写...

typedef unsigned char Uint8; //Always correct
typedef unsigned short int Uint16; //Not always true
typedef unsigned int Uint32; //Not always true

...在另一个平台上编译我的项目时,我可以编写这些 typedefs 来处理这个新平台,但我发现 c 的 limits.h 头文件包含一些预处理器 定义每种整数变量的大小。

我的主要目的是在我的 SWIG 脚本中创建这些 typedef,而不必担心我在哪个平台(或编译器)中编译我的项目。

现在,我的Config.i SWIG 文件如下所示:

%{
#include <limits.h>
#include <climits.h>
#include <SFML/Config.hpp>
%}

%include <SFML/Config.hpp>

而我用于生成包装器的 SWIG 命令是:

swig -c++ -lua -I/PathToSFML -I/PathToLimits ./SFML.i

我希望 SWIG 可以在 limits.h 文件中找到预处理器定义的变量,该文件由 &lt;SFML/Config.hpp&gt; 使用,但我无法完成这项工作......

是否有人对如何实现我的目标(每个平台的动态类型定义)有一些提示,或者知道如何让 swig 获得在limits.h 中定义的预处理器变量?

【问题讨论】:

  • “我为此任务选择的工具是 SWIG,因为我想让我的游戏可以用 python 或其他语言编写。”我喜欢 SWIG,但这不是使用它的正确理由。 SWIG 将需要特殊的语言特定编码。至少,如果您希望绑定实际上像语言一样工作。不存在与平台无关的语言绑定。
  • 哦,我知道。但是 SWIG 使移植到另一种语言的任务比使用 luabind 在 lua 中编写所有绑定以及随后在 python 中使用 boost 重写所有包装器更容易,例如。

标签: c++ c-preprocessor swig sfml


【解决方案1】:

limits.h 中定义的任何类型都不是标准的,可能不应该依赖。如果您想要跨平台的固定大小整数类型定义,C++11 标准库提供了cstdint 标头。此标头为您提供有符号和无符号 8、16、32 和 64 位整数的 typedef:int32_tuint32_tint8_t 等等。

大多数标准库实现在 C++11 之前提供 cstdint 作为扩展,但如果您的实现没有它,Boost 也会提供它。

【讨论】:

  • 我将答案归功于@dauphic,因为他给了我提示,让我得到了真正的答案。对于“真实”的答案,请查看我的答案帖子。谢谢 dauphic。
【解决方案2】:

感谢用户 dauphic 的回答,我尝试在示例中使用 &lt;stdint.h&gt;,然后在我的模块中运行 SWIG 时收到此错误消息:

/usr/include/stdint.h:44: Error: Syntax error in input(1).

在 Google 上搜索得到以下两个网页:

第二个给了我答案。

我的最终代码现在看起来像这样:

%module Config

%include <stdint.i>

//namespace sf // For some reason, not working when the namespace is here...
//{            // Turns out that I don't need the sf anyway...
typedef int8_t Int8;
typedef uint8_t Uint8;

typedef int16_t Int16;
typedef uint16_t Uint16;

typedef uint32_t Int32;
typedef uint32_t Uint32;
//}

如您所见,%include &lt;stdint.i&gt; 是 SWIG 中自 1.34 版以来的预定义模块(不太确定版本...在某处读过它并忘记了),它已准备好使用。

【讨论】: