0

我正在研究一些多平台 C++ 代码。因此需要使用 fopen、fgetpos 等。以下内容较早在 iOS 上运行,并且随着我更新到最新版本,它停止运行。

我在 Shaders 文件夹中有几个文本文件 Shader.vsh 和 Shader.fsh,它们被复制到包中。为了打开文件,我执行以下操作..

CFBundleRef mainBundle = CFBundleGetMainBundle();

CFStringRef cfstrFilename = CFSTRFromConstCharPtr( "Shader" );
CFStringRef cfstrFileType = CFSTRFromConstCharPtr( "vsh" );
CFStringRef cfstrSubDir = CFSTRFromConstCharPtr( "Shaders" );

CFURLRef resourcesURL = CFBundleCopyResourceURL( mainBundle, cfstrFilename, cfstrFileType, cfstrSubDir );

CFStringRef str = CFURLCopyFileSystemPath( resourcesURL, kCFURLPOSIXPathStyle );
CFRelease( resourcesURL );

char path[ PATH_MAX ];  
CFStringGetCString( str, path, FILENAME_MAX, kCFStringEncodingASCII );

CFRelease( str );

FILE* fp = fopen( path, "rb" );

此时,fp 为非 NULL。所以我认为它成功了。后来,当我尝试做

fpos_t pos;
int result = fgetpos( fp, &fpos_t );

结果 = -1 和 errno = 0x2,我认为这是找不到文件。

正如我之前提到的,这曾经在某个时候在以前的版本上工作。我再次开始处理这个问题,并在此过程中更新到最新的 XCode 等,然后事情就停止了。

我传递给 fopen 的文件路径原来是 /Users/shammi/Library/Application Support/iPhone Simulator/6.1/Applications/9132490F-71AC-4C61-A584-E8F6C5B261FF/TestApp.app/Shaders/Shader.vsh我能够在 finder/console 中查看并打开该文件并确认其有效。

我究竟做错了什么?是否有另一种选择可以让我使用便携式 IO 功能?

4

1 回答 1

0

发现了问题。我在这里没有提到的是上面两段代码之间发生的事情。在此之前,我曾经有自己的 ref 计数解决方案,最近改用 shared_ptr。我自己的参考计数解决方案允许隐式转换。使用 shared_ptr,您无法做到这一点。所以这里是确切的代码......

std::shared_ptr< BinaryStream > BundleNamespace::OpenStream( const char* _szPath,

BinaryStream::Mode _eMode )
{
    std::shared_ptr< BinaryStream > pStream = __super::OpenStream( _szPath, _eMode );
    if ( !pStream )
    {
        std::string strDir;
        std::string strFile;
        std::string strExt;

        SplitPath( _szPath, strDir, strFile, strExt );

        std::string strFullPath = GetResourcePathFor( strFile.c_str(), strExt.c_str(), strDir.c_str() );

        FILE* fp = fopen( strFullPath.c_str(), _eMode == BinaryStream::Mode_Read ? "r" : "w+b" );

        pStream = std::make_shared<FileStream>( fp, _eMode );
    }

    return pStream;
}

这里的问题是

    pStream = std::make_shared<FileStream>( fp, _eMode );

我的 FileStream 的析构函数调用 fclose(m_pFile)。这里的解决方法是将其更改为..

    pStream = std::static_pointer_cast< BinaryStream >( std::make_shared<FileStream>( fp, _eMode ) );`

此外,与尝试破译 errno 相比,使用 perror() 被证明更有用。

于 2013-06-24T02:08:23.937 回答