0

我正在尝试在 Android NDK 中加载 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

Sigh, I just realized the mistake. I allocate memory for pImageData, then set the point to the buffer. This does not sit well when I try to create an OpenGL texture with the pixel data. Modifying it so I memcpy the pixel data from (pBuffer + sizeof( TGA_HEADER) ) to pImageData fixes the problem.

于 2012-06-14T19:48:10.570 回答
0

为什么要 reinterpret_cast?您正在向 char* 添加一个整数;该操作产生一个 char*。不需要类型转换。

在 Android(以及一般的 ARM 设备上)指针杂耍的一个警告:ARM 无法从内存中读取/写入未对齐的数据。如果你读/写一个 int 大小的变量,它的地址必须是 4 的倍数;简而言之,是 2 的倍数。字节可以位于任何地址。据我所知,这不适用于呈现的代码段。但请记住。它偶尔会抛出二进制格式解析,尤其是从英特尔 PC 移植时。

简单地将未对齐的值分配给指针不会崩溃。取消引用它可能。

于 2012-06-14T19:04:58.850 回答