Справочная информация:
Я писал OpenGL-приложение "Hello Rectangle". Я хочу, чтобы он был автономным .app
, а не просто "исполняемым файлом UNIX". Код отлично работает из Terminal.app.
Я не использовал Xcode; Я очень недостаточно места на диске, и я не занимаюсь разработкой iOS.
Вместо этого я использую сваренный набор инструментов, включая gcc-8
, glfw
и glew
.
Я структурировал свой релизный каталог в соответствии с этим ТАК вопрос следующим образом:
Contents
├── Frameworks
│ ├── libGLEW.2.1.dylib
│ ├── libgcc_s.1.dylib
│ ├── libglfw.3.dylib
│ └── libstdc++.6.dylib
├── MacOS
│ ├── hello-rect <- the actual binary
│ └── launcher.sh <- entry wrapper for working dir as the above link suggests
├── Resources
│ ├── rect.frag
│ └── rect.vert
└── Info.plist
Я также изменил ссылку на dylibs в двоичном формате. Но это не будет работать.
После нескольких часов поиска в Google, этот SO ответ и SO вопрос и несколько других убедили меня, что я должен использовать CoreFoundation
для чтения этих двух шейдерных файлов (текстовый файл ) в Resources
.
Проблема:
Я попробовал следующий код (вставленный по ссылке выше с небольшим изменением), но он получает segfault:
const char* textFileReadCF(const char *&filename){
// Get a reference to the main bundle
CFBundleRef mainBundle = CFBundleGetMainBundle();
// Get a reference to the file's URL
CFStringRef filenameHandle = CFStringRef(filename);
// ------ segfault 11 here ------
CFURLRef fileURL = CFBundleCopyResourceURL(mainBundle, filenameHandle, NULL, NULL);
// Convert the URL reference into a string reference
CFStringRef filePath = CFURLCopyFileSystemPath(fileURL, kCFURLPOSIXPathStyle);
// Get the system encoding method
CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
// Convert the string reference into a C string
const char *path = CFStringGetCStringPtr(filePath, encodingMethod);
// the real read function, read in file and returns all as a big char* arr
return textFileRead(path);
}
// this runs fine before packing and I didn't change,
// just for the sake of completeness
const char *textFileRead(const char *filename){
std::ifstream shaderFile(filename);
std::ostringstream shaderBuffer;
shaderBuffer << shaderFile.rdbuf();
std::string shaderBufferStr = shaderBuffer.str();
// Warning: safe only until shaderBufferStr is destroyed or modified
char * ret = new char[shaderBufferStr.size()];
std::strcpy(ret, shaderBufferStr.c_str());
return ret;
}
textFileReadCF
будет вызван дважды с "rect.vert"
и "rect.vert"
(не буквальным, но const char*
, удерживающим их).
Понятия не имею, почему происходит сегфо. Я удостоверился, что есть один mainBundle
- assert
(опущен), и что filenameHandle
действителен, как я могу сказать, но в противном случае я не знаю, где искать.