Programlarımda SDL2'yi nasıl doğru kullanırım?
SDL2 kullanarak bir oyun yapmak istiyorum, ancak kodumu derleyemiyorum ve / veya çalıştıramıyorum, lütfen yardım edin!
SDL2'nin kurulumu oldukça zordur ve genellikle hevesli oyun geliştiricilerin kullanmaya çalıştığı ilk kitaplıktır.
Bu gönderi, SDL2 kurulumuyla ilgili yaygın sorunlar için kanonik bir kopya olarak tasarlanmıştır.
Yanıtlar
Bu yanıt, MinGW / GCC ile ilgilidir, Visual Studio ile değil.
Bu cevap öncelikle Windows ile ilgilidir. Diğer işletim sistemlerinde işler daha kolaydır, özet için cevabın altına bakın.
Bu cevabı bir aceminin bile kullanabilmesi için son derece basit tutmaya çalıştım.
Genel hatalar
Alabileceğiniz genel hatalar şunlardır:
SDL.h: No such file or directory(derlerken)undefined reference toçeşitli işlevler (bağlanırken)- Gizemli
.dllilgili hatalar (programınızı çalıştırırken).
Bu liste kötüden iyiye doğru sıralanmıştır. Bir şeyi değiştirir ve farklı bir hata alırsanız, işleri daha iyi mi yoksa daha kötü mü yaptığınızı anlamak için bu listeyi kullanın.
Tüm bunları nasıl düzelteceğinizi öğrenmek için aşağıdaki cevaba bakın.
Önsöz
Hataları düzeltmeye başlamadan önce size söylemek istediğim bazı şeyler.
0. Kötü tavsiyelere uymayın.
Bazı kaynaklar yapmak önerir #define SDL_MAIN_HANDLEDya #undef main. Bunu yapma. Bu çözümler, SDL2'nin kullanım amacından farklıdır ve doğru kurulum ile ASLA gerekli değildir.
Bazıları bunların amaçlanan yoldan daha iyi olduğunu iddia ediyor, ancak önce amaçlanan yolu öğrenmeyi, sonra farkın ne olduğunu öğrenmeyi ve ardından eğitimli bir karar vermeyi öneriyorum .
1. Doğrudan konsoldan nasıl derleyeceğinizi öğrenin, daha sonra bir IDE kullanmaya başlayabilirsiniz. Bir IDE kullanıyorsanız, herhangi bir IDE yapılandırma problemini ortadan kaldırmak için öncelikle programınızı doğrudan konsoldan derleyebildiğinizden emin olmanızı öneririm. Bunu anladıktan sonra, IDE'nizde aynı derleyici seçeneklerini kullanabilirsiniz.
Ayrıca CMake ile ilgili sorunları ortadan kaldırmak için yeni başladıysanız CMake'den kaçınmanızı öneririm. Daha sonra kullanmaya başlayabilirsiniz.
2. Doğru SDL2 dosyalarını indirin . Doğru dosyalara sahip olduğunuzdan emin olun. Sen denilen arşivi gerek SDL2-devel-2.0.x-mingw.tar.gzdan burada .
Herhangi bir dizinde, tercihen kaynak kodunuzun yakınında bir yerde paketini açın. Doğrudan derleyici dizinine paket açmak genellikle kötü bir uygulama olarak kabul edilir.
3. Derleyici bayrakları ve bağlayıcı bayrakları arasındaki farkı bilin . "Bayrak", programınızı oluştururken komut satırında belirlediğiniz bir seçenektir. Tek bir komut kullandığınızda, örneğin g++ foo.cpp -o foo.exe, tüm bayraklarınız aynı yere (bu tek komuta) eklenir.
Ancak programınızı iki adımda oluşturduğunuzda, örneğin:
g++ foo.cpp -c -o foo.o(derleniyor)g++ foo.o -o foo.exe(bağlantı)
iki komuttan hangisine bayrak ekleneceğini bilmeniz gerekir. İlk komuta eklenmesi gereken bayraklar "derleyici bayrakları" ve ikinciye eklenmesi gereken bayraklar "bağlayıcı bayrakları" dır. Aşağıdaki cevapta, size bir bayrak eklemenizi söylerken, bunun bir derleyici bayrağı mı yoksa bağlayıcı bayrağı mı olduğunu belirteceğim.
Çoğu IDE, derleyici ve bağlayıcı bayraklarını ayrı ayrı belirtmenizi gerektirir, bu nedenle şimdi tek bir komut kullansanız bile , hangi bayrağın nereye gittiğini bilmek iyidir.
Aksi belirtilmedikçe, bayrakların sırası önemli değildir.
SDL.h: No such file or directory
Veya dahil olmak üzere ilgili benzer hatalar SDL.hveya SDL2/SDL.h.
Derleyicinize dizinin nerede SDL.holduğunu söylemeniz gerekir . İndirdiğiniz SDL dosyalarındadır (önsöze bakın).
Derleyici işaretlerinize aşağıdakileri ekleyin: -Ive ardından bir dizin.
Örnek: -IC:/Users/HolyBlackCat/Downloads/SDL2-2.0.12/x86_64-w64-mingw32/include/SDL2. (Göreli yollar da çalışır, örneğin -ISDL2-2.0.12/x86_64-w64-mingw32/include/SDL2.)
Nasıl yazdığınıza bağlı olarak bayrağın farklı olabileceğini unutmayın #include:
- Bunu yaparsanız
#include <SDL.h>, yolun bitmesi gerekir.../include/SDL2(yukarıdaki gibi). Bu önerilen yoldur. - Bunu yaparsanız
#include <SDL2/SDL.h>, yolun bitmesi gerekir.../include.
undefined reference to çeşitli fonksiyonlar
Hata mesajında çeşitli SDL_...işlevler (genellikle programınızda kullandıklarınız) ve / veya belirtilir WinMain. Bundan bahsediliyorsa SDL_main, undefined reference to SDL_mainaşağıdaki " sadece" bölümüne bakın.
Aşağıdaki bağlayıcının bayrakları eklemeniz gerekir: -lmingw32 -lSDL2main -lSDL2. Sıra önemlidir. Bayraklar herhangi bir .c/ .cpp/ .odosyadan SONRA görünmelidir .
Yazma -lSDL2main -lSDL2, bağlayıcıya libSDL2main.a, indirdiğiniz SDL dosyalarında bulunan libSDL2.a(veya libSDL2.dll.a) adlı dosyaları kullanmasını söyler . Bağlayıcıya bu dosyaları nerede arayacağını söylemek için bir bayrağa daha ihtiyacınız var.a . Bağlayıcı bayraklarınıza aşağıdakileri ekleyin: -Lve ardından dizin.
Örnek: -LC:/Users/HolyBlackCat/Desktop/SDL2-2.0.12/x86_64-w64-mingw32/lib. (Göreli yollar da çalışır, örneğin -LSDL2-2.0.12/x86_64-w64-mingw32/lib.)
Tüm bu bayrakları ekledim ve hiçbir şey değişmedi:
Bunu yaptıysanız ve hala aynı undefined referencehataları alıyorsanız, muhtemelen yanlış SDL .adosyalarını kullanıyorsunuzdur. İndirdiğiniz arşiv iki dosya grubu içerir: i686-w64-mingw32(32 bit) ve x86_64-w64-mingw32(64 bit). Derleyicinizle eşleşen, 32 bit veya 64 bit de olabilen dosyaları kullanmanız gerekir. (8*sizeof(void*))Derleyicinizin 32 bit mi yoksa 64 bit mi olduğunu görmek için yazdırın . Doğru dosyaları kullandığınızı düşünseniz bile, emin olmak için diğerlerini deneyin.
MinGW sürümlerinden birkaçı -m32ve -m64bayrakları kullanılarak 32 bit ve 64 bit modlar arasında geçiş yapılabilir (bunların muhtemelen hem derleyici hem de bağlayıcı bayraklarına eklenmesi gerekir). Bunları da deneyebilirsiniz.
Ben olsun undefined referencebelirli bir işleve:
• undefined reference to WinMainsadece
Tümü önceki bölümde ele alınan üç olasılık vardır:
-lSDL2mainBayrağı unuttun .- Kullandığınız
libSDL2main.adosya, derleyicinizle eşleşmiyor (32-bit dosya ile 64-bit derleyici veya tersi). -lSDL2mainBayrağı bazı.c/.cpp/.odosyaların soluna koyarsınız . Her zaman sağda olmalı.
Kaçınmaya çalışın #define SDL_MAIN_HANDLEDveya #undef mainbu sorunu çözerken açıklama için giriş bölümüne bakın.
• undefined reference to SDL_mainsadece
Bir mainişleve sahip olmalısın . Sizin mainfonksiyonu gibi bakmak gerekir int main(int, char **). DEĞİL int main() ve DEĞİL void main() . Bu, SDL2 tuhaflıklarından biridir.
Herhangi bir parametre adının eklenmesine izin verilir, örn int main(int argc, char **argv). Ayrıca ikinci parametre olarak yazılabilir char *[]veya bir adla: char *argv[]. Başka hiçbir değişikliğe izin verilmez.
Kaçınmaya çalışın #define SDL_MAIN_HANDLEDveya #undef mainbu sorunu çözerken açıklama için giriş bölümüne bakın.
.dllilgili hatalar
Başarıyla oluşturdunuz .exe, ancak bazı .dlls'den bahseden gizemli hatalar nedeniyle çalıştıramıyorsunuz . Neredeyse oradasın!
.exeEğer geçirilmesi gerekir bazı yapılan .dllrun s. Eğer onları bulamazsa size söyler ve kaçmayı reddeder. Bu kolay. Ayrıca, yüklediğiniz diğer programlardan kalan yanlış sürümlerini de bulabilir, sonra çok şifreli hatalar alırsınız.
Programınız .dllfarklı konumlardaki URL'leri arayacaktır , ancak en güvenilir çözüm onları .exe. İlk önce bu dizin aranır, böylece başka bir .dllyerde sahip olabileceğiniz e-postaların diğer sürümleri karışmaz.
Sen gerekir hangi anlamaya .dllnerede program ihtiyaçlarını s ve dizine koyun .exeis (sistem dışında .dllkopyalamak gerekmez ler).
Alabileceğiniz iki tür hata vardır:
Size neyin
.dlleksik olduğunu söyleyen bir hata .SDL2.dllkayıp. - İndirdiğiniz SDL dosyalarında.Dosyaların iki farklı
SDL2.dllURL içerdiğine dikkat edin : 32 bitlik bir (i686-w64-mingw32dizinde) ve 64 bitlik bir (girişx86_64-w64-mingw32). Doğru olanı alın, gerekirse ikisini de deneyin.Biri
.dlleksik. - Derleyicinizle birlikte gönderilir. Bulunduğunuz dizine bakıngcc.exe.Birini kopyalarsanız
.dllve daha fazlasını isterse, bu normaldir, bunu ~ 3 kez tekrarlamanız gerekebilir.
Şifreli bir
.dllhata. - Programınız.dll, sisteminizde bir yerde yanlış bir sürüm buldu .Sistem dışı tüm dosyaları
.dllbulunduğunuz dizine kopyalamanız gerekir.exe.Önce kopyalayın
SDL2.dll(SDL2.dllnerede bulacağınızla ilgili olarak yukarıdaki " eksik" bölümüne bakın ).Ardından,
.dllderleyici dizininizden (bulunduğu dizingcc.exe) aşağıdaki URL'leri kopyalayın :libgcc_s_seh-1.dll(ad, MinGW sürümünüze bağlı olarak değişebilir, ancak her zaman ile başlayacaktırlibgcc)libstdc++-6.dll(yalnızca C ++ için, C ile yazıyorsanız atlayın)libwinpthread-1.dll(ad, MinGW sürümünüze bağlı olarak değişebilir, ancak her zaman belirtilecektirthread; bazı sürümler bunu hiç kullanmaz)
Bu, tüm hatalarınızı düzeltmelidir. Daha fazlasını öğrenmek istiyorsanız veya yardımcı olmadıysa:
.dllS hakkında daha fazla bilgi
Bağlayıcı işaretini kullanarak .exeherhangi bir (sistem dışı) ' .dllye bağlı olmayan bir şey yapmak mümkündür -static, buna "statik bağlama" denir. Bu nadiren yapılır ve yukarıdaki adımları doğru bir şekilde yaptıysanız bunu yapmanız gerekmez. Bu, normalden farklı bağlayıcı bayrakları gerektirir (yaklaşık 20 tanesi), sdl2.pctam bayraklar için SDL ile birlikte gönderilen dosyaya bakın (bunlar Libs.privatebölümdedir).
Önceki bölümde .dllsize programınızın neye bağlı olduğunu anlatmıştım . Nasıl bildim Bunu kendiniz anlamanın birkaç yolu vardır:
Kaba yol:
Konsolu açın,
cdbulunduğunuz dizine girin.exe, ardından yazınset PATH=(endişelenmeyin, bu sistemPATHayarınızı değiştirmez ve yalnızca mevcut konsol oturumunu etkiler).Daha
.dllönce oraya kopyalamış olabileceğiniz tüm URL'leri kaldırın .Şimdi
.exebu konsoldan çalıştırırsanız, yalnızca sistem.dlle- postalarını bulabilir . Yalnızca geçerli dizinde (hiçbiri olmayan) sistem dışı olanları arayacaktır. Şimdi neyin.dllgerekli olduğunu söyleyen net hata mesajları alacaksınız ve çalışmaya başlayana kadar bunları tek tek kopyalayabilirsiniz. Bu şekilde.dll, programınızın kullandığı sistem dışı tüm leri bileceksiniz .Bu yöntemin tamamen kusursuz olmadığını unutmayın.
C:\Windowsve iç içe geçmiş dizinlerden bazıları bu durumda bile her zaman aranır. Normalde.dll, sistemdeki tek e- postaların olup olmadığı önemli değildir , ancak bazı berbat yükleyiciler.dllorada bir özel kopyaladıysa , bu yöntem doğru çalışmayacaktır.Orada olmaması gereken
C:\Windowsdizinler için iç içe geçmiş dizinlerde arama yapmak ve.dllbunları silmek iyi bir fikirdir . Derleyicinizle (bulunduğunuz dizinde ) birlikte gönderilenSDL2.dllherhangi bir.dllURL'yi arayıngcc.exe.Medeni yol:
Dependency Walker veya gibi bir araç kullanın
ntldd. Çıktılarını gözden geçirmeniz ve her birinin.dllsistem mi yoksa sistem dışı mı olduğunu belirlemeniz gerekir . Bir.dllderleyicinizle birlikte gönderilirse veya (SDL2.dll) kullandığınız bir kitaplığa aitse , o zaman sistem dışıdır. Kalan herhangi bir.dlls sistem olanlardır, onları dikkate almayın.
Diğer problemler
S: Programım , SDL kullanarak açtığım pencerelere ek olarak, çalıştırdığımda her zaman bir konsol penceresi açar . Ondan nasıl kurtulurum?
- C:
-mwindowsBağlayıcı bayraklarına ekleyin .
- C:
S: Programımın varsayılan dosya simgesi var , ancak özel bir tane istiyorum.
C: Simgeniz
.icoformatta olmalıdır ..rcUzantısı olan bir dosya oluşturun (diyelimicon.rc), içine şunu yazın:MAINICON ICON "icon.ico"(ilk bölüm rastgele bir isimdir, onu değiştirebilirsiniz; ikinci bölüm her zaman olmalıdırICON, üçüncü bölüm simgeye giden yoldur). Bir dosyayı dönüştürme.okullanarakwindres -i icon.rc -o icon.o(windresprogram derleyici ile dağıtılmaktadır). Bağlanırken ortaya çıkan.odosyayı belirtin , örng++ foo.cpp icon.o -o foo.exe.SDL2'nin son sürümleri, pencere simgesiyle aynı simgeyi kullanmak gibi güzel bir özelliğe sahiptir, bu nedenle kullanmanız gerekmez
SDL_SetWindowIcon.
S: Hata alıyorum
'SDL_VideoMode' wasn't declared in this scope.- C:
SDL_VideoModeSDL1.2'de vardı, ancak SDL2'nin bir parçası değil. Kodunuz eski SDL1.2 için yazılmıştır. Yeni SDL2 ile ilgilenen daha iyi bir eğitim bulun.
- C:
Windows kullanmıyorum, neyi farklı yapıyorum?
Yukarıdaki cevabın tamamı öncelikle MinGW ve Windows'u hedeflemektedir. Windows'ta değilseniz işler daha kolay hale gelir:
.dllİlişkili sorunlar yok .SDL2'yi manuel olarak indirmenize gerek yok, paket yöneticinizde olması gerekir.
Hangi derleyici veya bağlayıcı bayraklarının kullanılacağını düşünmeye gerek yok:
pkg-config --cflags sdl2size derleyici bayraklarını söyleyecektir.pkg-config --libs sdl2size bağlayıcı bayraklarını söyleyecektir.--staticStatik bağlantı için bayraklar istiyorsanız ekleyin .
İhtiyacın yok
-lSDL2mainve bununla ilgili hiçbir sorun yokSDL_main.
Diğer yandan:
Programlarınızı diğer insanlara dağıtmak zorlaşır,
.dllprogramınızla birlikte bir sürü e-posta gönderemezsiniz .Özel bir simge ayarlama süreci farklıdır.
Alternatif yaklaşım: Windows'ta Linux benzeri bir ortam kullanın
Önceki bölümün kitaplıkları yükleme ve derleyici bayraklarını otomatik olarak belirleme ile ilgili kısmı kulağa uygun geliyor mu? Buna Windows'ta da sahip olabilirsiniz.
MSYS2'yi indirin. Bir paket yöneticiniz (SDL'yi kurabileceğiniz), güncel derleyiciler ve Linux'tan (dahil pkg-config) taşınan bir dizi ortak yardımcı programınız olacak . Bu, Windows'a özgü sorunların çoğunu çözer.
Mac'te XCode için takip ettiğim şey şu (g ++ yüklemeliyim):
sdl bağlantısı:
g++ main.cpp -o main $(sdl2-config --cflags --libs)
XCODE proje adımları:
terminal uygulamasını açın (macOS)
AYARLAR OLUŞTURUN ('tümü' ve 'birleşik' arama çubuğunu seçin: "arama" girin)
"başlık arama yollarına tıklayın (yol sağ taraftaki tıklama)
Ekle:
/usr/local/includeYAPI AŞAMALARI -> BAĞLANTI İKİLİ KÜTÜPHANELER (artıya tıklayın)
yazın
SDL-> "başka ekle" yi tıklayınbasın: command+ SHIFT+ g(arama çubuğunu getirmek için)
yazın:
usr/local/Cellarşuraya gidin: SDL2 -> 2.0.8 -> lib -> libSDL2-2.2.0.dylib (kısayol olmadığından emin olun)
Visual Studio için bir çözüm:
Neden bir paket yöneticisi kullanmıyorsunuz? Vcpkg kullanıyorum ve 3. parti kitaplıkları tüketmeyi çok kolaylaştırıyor. Vcpkg kaynağını alın ve güvenli bir yere çıkartın, örneğin C:/önyükleme betiğini çalıştırın bootstrap-vcpkg.bat, bu vcpkgyürütülebilir dosya oluşturacaktır . Ardından vcpkg integrate install, vcpkg ile yüklenen kitaplıkları Visual Studio'da kullanılabilir hale getirmek için çalıştırın .
İhtiyacınız olan kitaplığı arayın:
vcpkg search sdl
imgui[sdl2-binding] Make available SDL2 binding
libwebp[vwebp-sdl] Build the vwebp viewer tool.
magnum[sdl2application] Sdl2Application library
sdl1 1.2.15#12 Simple DirectMedia Layer is a cross-platform development library designed to p...
sdl1-net 1.2.8-3 Networking library for SDL
sdl2 2.0.12-1 Simple DirectMedia Layer is a cross-platform
...
İle yükleyin: vcpkg install sdl2.
Şimdi sadece SDL2 başlıklarını eklemeye ihtiyacınız var ve her şey kutudan çıktığı gibi çalışacaktır. Kitaplık otomatik olarak bağlanacaktır.
Burada vcpkg hakkında daha fazla bilgi edinebilirsiniz .