0

AndroidNDKにTGAファイルを読み込もうとしています。

AssetManagerを使用してファイルを開き、TGAファイルの内容全体をメモリバッファーに読み込んでから、そこからピクセルデータを抽出しようとします。

ファイルのTGAヘッダー部分を問題なく読み取ることができますが、メモリポインタをTGAヘッダーを超えて進めようとすると、アプリがクラッシュします。メモリポインタを進めようとしないと、クラッシュしません。

Android NDKには、ポインター演算に関する何らかの制限がありますか?

コードは次のとおりです。

この関数はアセットファイルを開きます:

char* GEAndroid::OpenAssetFile( const char* pFileName )
{
char* pBuffer = NULL;

AAssetManager* assetManager = m_pState->activity->assetManager;
AAsset* assetFile = AAssetManager_open(assetManager, pFileName, AASSET_MODE_UNKNOWN);
if (!assetFile) {
    // Log error as 'error in opening the input file from apk'
    LOGD( "Error opening file %s", pFileName );
}
else
{
    LOGD( "File opened successfully %s", pFileName );
    const void* pData = AAsset_getBuffer(assetFile);
    off_t fileLength = AAsset_getLength(assetFile);
    LOGD("fileLength=%d", fileLength);

    pBuffer = new char[fileLength];
    memcpy( pBuffer, pData, fileLength * sizeof( char ) );
}

return pBuffer;
}

そして、ここで私のテクスチャクラスでそれをロードしようとします:

char* pBuffer = g_pGEAndroid->OpenAssetFile( fileNameWithPath );

TGA_HEADER textureHeader;
char    *pImageData = NULL;
unsigned int bytesPerPixel = 4;

    textureHeader = *reinterpret_cast<TGA_HEADER*>(pBuffer);
    // I double check that the textureHeader is valid and it is.

    bytesPerPixel   = textureHeader.bits/8;             // Divide By 8 To Get The Bytes Per Pixel
    m_imageSize     = textureHeader.width*textureHeader.height*bytesPerPixel;   // Calculate The Memory Required For The TGA Data


    pImageData = new char[m_imageSize];
    // the line below causes the crash
    pImageData = reinterpret_cast<char*>(pBuffer + sizeof( TGA_HEADER)); // <-- causes a crash

上記の行を次の行に置き換えると(間違っていても)、明らかにテクスチャが台無しになっていますが、アプリは実行されます。

    pImageData = reinterpret_cast<char*>(pBuffer); // <-- does not crash, but obviously texture is messed up.

誰かアイデアはありますか?

ありがとう。

4

2 に答える 2

0

なぜreinterpret_cast?char*に整数を追加しています。その操作はchar*を生成します。タイプキャストは必要ありません。

Android(および一般的なARMデバイス)でのポインタージャグリングに関する1つの注意点:ARMは、メモリからアラインされていないデータを読み書きできません。intサイズの変数を読み書きする場合は、4の倍数のアドレスにある必要があります。略して、2の倍数。バイトは任意のアドレスに置くことができます。これは、私が見る限り、提示されたスニペットには適用されません。ただし、覚えておいてください。特にIntelPCから移植された場合は、バイナリ形式の解析がときどきスローされます。

アラインされていない値をポインタに割り当てるだけではクラッシュしません。間接参照する可能性があります。

于 2012-06-14T19:04:58.850 に答える
0

ため息、私はちょうど間違いに気づきました。pImageDataにメモリを割り当ててから、ポイントをバッファに設定します。ピクセルデータを使用してOpenGLテクスチャを作成しようとすると、これはうまくいきません。ピクセルデータを(pBuffer + sizeof(TGA_HEADER))からpImageDataにmemcpyするように変更すると、問題が修正されます。

于 2012-06-14T19:48:10.570 に答える