1

我目前有一个名为 TextureObject 的类。在创建函数中,我创建纹理,并将类中的 LPCSTR 分配给函数中给定的参数。当我稍后返回该 LPCSTR 时,它以一种意想不到的方式返回。

某些类型名称和函数来自 DirectX 11,请忽略它们。

代码:

h 文件:

class TextureObject
{
public:
    ID3D11ShaderResourceView *pTexture;
    LPCSTR GetFilename() const { return *FFilename; }

    bool IsNotNull;
    void CreateTexture(ID3D11Device &dev,LPCSTR Filename);
    void ReCreate(ID3D11Device &dev);
    void Release();
    int relativeId;
private:
    LPCSTR *FFilename;
};

.cpp 文件:

void TextureObject::CreateTexture(ID3D11Device &dev,LPCSTR Filename)
{
    D3DX11CreateShaderResourceViewFromFile(
            &dev,        // the Direct3D device
            Filename,    // load Wood.png in the local folder
            NULL,        // no additional information
            NULL,        // no multithreading
            &pTexture,   // address of the shader-resource-view
            NULL);       // no multithreading
    FFilename = new LPCSTR(Filename);
    IsNotNull = true;
}

void TextureObject::ReCreate(ID3D11Device &dev)
{
    CreateTexture(dev, *FFilename);
}

在 CreateTexture 函数中使用 vs 2012 调试器时,Filename 调试器值为:

0x0a06fed0 "C:\Users\Utilizador\Desktop\particle.png"

这对我来说是完美的!当我分配班级的 FFilename 时:

FFilename = new LPCSTR(Filename);

没关系。当我在此函数范围内检查 FFilename 的值时,它与 Filename 的值相同。但是当我使用 GetFilename 时,事情开始变得疯狂:

 = 0x0a06fed0 "îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþü =I.C"

嗯,我刚认识你,这很疯狂,但是……这是我的价值。麦凯?

好吧,请帮助我。谢谢你

4

3 回答 3

2

创建指针FFilename时,您正在使用另一个指针对其进行初始化。这不会复制字符串,现在您有两个指向同一事物的指针。想必那个东西是临时对象,以后去看的时候已经失效了。

我建议std::string改用它,它更不容易出错。该c_str方法可以随时获取LPCSTR

于 2012-10-23T21:55:02.157 回答
2

您没有复制字符串。您正在复制指针。我想你可能想复制字符串,因为你不能保证调用者的指针在以后仍然会引用有效数据。

LPCSTR只是一个const char*。可能有一个相应的 windows 调用,但我只是strdup用来复制字符串。

定义FFilenameLPCSTR

LPCSTR FFilename;

接着:

void TextureObject::CreateTexture(ID3D11Device &dev,LPCSTR Filename)
{
    D3DX11CreateShaderResourceViewFromFile(
            &dev,        // the Direct3D device
            Filename,    // load Wood.png in the local folder
            NULL,        // no additional information
            NULL,        // no multithreading
            &pTexture,   // address of the shader-resource-view
            NULL);       // no multithreading
    FFilename = strdup(Filename);
    IsNotNull = true;
}

void TextureObject::ReCreate(ID3D11Device &dev)
{
    CreateTexture(dev, FFilename);
}

由于您使用的是 C++,因此您可以自由使用std::string,当对象被销毁时会自动清理。

于 2012-10-23T21:56:10.243 回答
1

正如 marcin_j 所说,使用 std::[w]string。至于线路:

FFilename = new LPCSTR(Filename);

它只是为指针分配 4 个字节并将其初始化为文件名字符串。它实际上并没有复制字符串。因此,您仍然可以使用该字符串,但它归调用 TextureObject::CreateTexture 的人所有,并且可能在 TextureObject 仍在引用它时被释放。

将类更改为:

class TextureObject      
{      
public:      
    // ...all the same stuff as before...

private:      
    wstring FFilename;  // it's better to store filenames as Unicode
};

以及以下方法:

void TextureObject::CreateTexture(ID3D11Device* dev, const wstring& Filename)        
{        
    D3DX11CreateShaderResourceViewFromFile(        
            dev,        // the Direct3D device        
            Filename.c_str(),    // load Wood.png in the local folder        
            NULL,        // no additional information        
            NULL,        // no multithreading        
            &pTexture,   // address of the shader-resource-view        
            NULL);       // no multithreading        

    FFilename = Filename;
    IsNotNull = true;        
}        

void TextureObject::ReCreate(ID3D11Device* dev)        
{        
    CreateTexture(dev, FFilename.c_str());        
}        
于 2012-10-23T22:06:26.963 回答