使用 C++ 入口点让 SDL 在 OSX 上工作

Posted

技术标签:

【中文标题】使用 C++ 入口点让 SDL 在 OSX 上工作【英文标题】:Getting SDL to work on OSX with C++ entry point 【发布时间】:2012-06-09 23:43:06 【问题描述】:

我已经设置了一个用于构建我的软件的系统,使用 makefile 和命令行工具。

我已经能够轻松地修改 makefile 以支持我的 Mac(现在是 10.7.4),所以我试图让我的代码独立于 XCode 工作。一旦我开始将东西移植到 ios,我就会处理 XCode。我希望 makefile 解决方案(虽然我的代码库仍然可以通过所述 makefile 管理)为我提供更好的可移植性和自动化选项。

我正在体验here 所描述的内容。代码编译,运行时遇到问题。

起初我使用 SDL 站点上二进制下载的 SDL 框架 (-framework SDL),所以我想我可以通过从源代码正确构建 SDL 来解决问题。我已经这样做了,现在正在链接到 libSDL.alibSDLMain.a。这反过来又要求我包含这些额外的框架才能成功编译(我根据sdl-config --static-libs 的输出得出了列表:

-framework Cocoa -framework IOKit -framework AudioToolbox -framework AudioUnit -framework Carbon -framework ApplicationServices 

但是我仍然有同样的问题,文章解释这与缺少这个有关:

[NSApplication sharedApplication];

我的代码没有 Obj-C 代码。不过,我很高兴将一些 Obj-C 插入其中。我添加了其中一个软件包附带的SDLMain.m,但链接器有问题:ld: duplicate symbol _main

好的,所以我不会这么轻易就逃脱的。

我缺少哪些可以让我初始化 NSApplication 的小部件?有没有办法在没有单独的源文件(来自我的Main.cpp)的情况下做到这一点,现在必须是 Obj-C?是否有一些我可以调用 sharedApplication 的 C/C++ 包装函数?

【问题讨论】:

【参考方案1】:

如果您使用 libSDLmain 链接或包含 SDLMain.m,则您的入口点必须改为 SDL_main:

extern "C" int SDL_main(int argc, char **argv)


extern "C" 考虑到您使用的是 C++ 的事实。)

libSDLmainSDLMain.m 中包含的“真实”main 进行必要的 Mac 特定准备,然后调用 SDL_main

【讨论】:

那为什么我的代码与libSDLMain.a链接时会编译? SDL_main.h 标头包含一个将main 函数重命名为SDL_main 的宏。【参考方案2】:

也有一个纯 C 解决方案:做编译器的工作,将 Objective-C 调用降低为一个 C 调用,或一组 C 调用。

#include <objc/runtime.h>
#include <objc/message.h>

static void createSharedApplication(void)

    id myNSApplication = objc_getClass("NSApplication");
    SEL mySharedApplication = sel_registerName("sharedApplication");
    id (*myMsgSend)(id, SEL) = (id (*)(id, SEL))objc_msgSend;

    myMsgSend(myNSApplication, mySharedApplication);

但是,正如您所见,这不是很优雅。

【讨论】:

【参考方案3】:

RavuAlHemio 应归功于他,因为他为我指出了有关 SDL 正在使用入口点做什么(试图做什么)的足够信息。然后我稍微编辑了我的代码,来自

#undef main
int main(int argc,char *argv[]) 

int main(int argc,char *argv[]) 

我使用第一种方式的唯一原因是因为在 Windows 上通过 MinGW(但不是 Linux)stdout 和 stderr 被重定向到文件而不是放在终端上。我现在必须为此想出一个更优雅的解决方案。

无论如何,这已经解决了问题。

【讨论】:

是的,这是因为 SDLmain 必须在 Windows 上以某种方式跟踪标准 I/O,但不会在每次启动时弹出烦人的终端窗口。

以上是关于使用 C++ 入口点让 SDL 在 OSX 上工作的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Kivy 1.9.1 或 1.9.2 在 OSX 10.12.2 上使用 SDL2 而不是 pygame?

当 OSX 不再支持 OpenGL 时,SDL 是不是仍会正式支持 OSX?

我的 C++ OpenGL SDL 程序没有按预期工作

在 OSX 上的核心配置文件上获取可用的 opengl 扩展

OSX 上的 SDL + OpenGL:NSAutoreleaseNoPool()

SLD2:使用 SDL2_gfx 和 AntTweakBar 在 OS X 上出现奇怪的渲染错误