2010-06-19 98 views
7

OS X上的SDL使用預處理器技巧將main()與它們自己的入口點重疊,該入口點寫在Objective C中,該入口點調用用戶的main。OS X上的Haskell SDL

這些技巧使非C SDL用戶(例如:Haskell綁定)的生活變得非常困難。

有沒有很好的理由呢?

爲什麼SDL無法在SDL_init中執行objective-C可可初始化?

回答

5

Mac OS X的方法與其他非Linux平臺(Windows,舊Mac,BeOS)的方法沒有多大區別。你可以問的SDL開發商自己,爲什麼他們這樣做的,但我可以看到,他們可能選擇這樣做有幾個原因:

  • 這使的SDL代碼,其重點是初始化SDL特有的依賴子系統(視頻,音頻,定時等)僅限於SDL特別設計的特定子系統。即這樣,SDL保持精簡和平均。
  • 它避免了必須爲應用程序初始化引入一個新的平臺特定的子系統。並不是每個人都希望SDL爲Mac應用程序設置的基本應用程序對象和菜單,而不是一個漫長的過程 - 所以如果您打算將它放入SDL_init,則需要將其設置爲可選子系統因爲不會給不需要它的開發者帶來不便。
  • 它正確地處理控制反轉,這正是Mac OS X和其他應用程序框架通常運行的方式,同時保持了SDL例程的操作語義。 SDL_init假定它將在初始化完成後返回給調用者,但如果您嘗試了天真地創建SDL_init中的應用程序對象並調用[app run]來完成初始化應用程序並啓動,則永遠不會返回。如果你沒有在那裏調用run,你必須創建一個單獨的SDL函數來設置應用程序運行循環。這可能會使SDL庫變得複雜。所選擇的方法避免了這一切,通過讓框架首先處理所有的應用程序,並調用applicationDidFinishLaunchingSDL_main()例程。
  • 它可以很容易地將在Linux上編碼的SDL演示轉換爲Mac OS X.您甚至不必重命名主 - main()SDL_main()的預處理器重命名爲您照顧!

我猜這些原因中的最後一個是主要在SDL_main.h,這是我認爲是一個醜陋的黑客重新定義的主要驅動程序。

如果你準備放棄跨平臺移植的那個水平是你的庫和應用程序,我建議簡單地修改你的SDL_main.h刪除以下行:

#define main SDL_main 

,並刪除以下從您的項目中SDLMain.m

#ifdef main 
# undef main 
#endif 

你甚至不應該需要重新編譯SDL如果你這樣做。請注意,SDLMain.m已經設置爲在沒有預處理器攻擊的情況下調用SDL_main(),並且SDL中沒有其他內容會使用此功能,所以通過這種方式,您可以簡單地將SDL_main()作爲遊戲的入口點。

如果你想要去的其他方式,接管main()自己,你還是會想擺脫在SDL_main.h#define main SDL_main破解的,但除此之外,你不受惠於SDL提供了main()您。首先,請注意SDLMain.{h,m}不屬於本庫的一部分;你必須將它們分別包含在你的項目中。二,請注意以下幾點意見中SDLMain.h

/* SDLMain.m - main entry point for our Cocoa-ized SDL app 
     Initial Version: Darrell Walisser <[email protected]> 
     Non-NIB-Code & other changes: Max Horn <[email protected]> 

    Feel free to customize this file to suit your needs 
*/ 

這聽起來很像一個邀請去滾你自己,如果這些工作不適合你,首先SDLMain.{h,m}的一種模式。如果你自己動手,你可以做你想做的事!對於這個問題,你可以使用HOC在Haskell中編寫相當於SDLMain.m,如果這就是你想要的。除非你是HOC的專家,否則我會保持簡單。