【问题标题】:Getting SDL to work on OSX with C++ entry point使用 C++ 入口点让 SDL 在 OSX 上工作
【发布时间】: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++ 包装函数?

【问题讨论】:

    标签: c++ objective-c macos opengl sdl


    【解决方案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,但不会在每次启动时弹出烦人的终端窗口。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      • 2016-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多