我目前有一个名为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"
嗯,我刚认识你,这很疯狂,但......这是我的价值所在。 mKay?
好的,请帮帮我。谢谢
答案 0 :(得分:2)
当您创建指针FFilename
时,您将使用另一个指针初始化它。这不会复制字符串,现在你有两个指向同一个东西的指针。据推测,这个东西是一个临时对象,当你以后再看它时,它就不再有效了。
我建议使用std::string
代替它,它更不容易出错。 c_str
方法可以随时获得LPCSTR
。
答案 1 :(得分:2)
您没有复制字符串。您正在复制指针。我想你可能想要复制字符串,因为你不能保证调用者的指针仍会在以后引用有效数据。
LPCSTR
只是const char*
。可能有相应的Windows调用,但我只是使用strdup
来复制字符串。
将FFilename
定义为LPCSTR
:
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
,当对象被销毁时,它将自动清除。
答案 2 :(得分:1)
正如marcin_j所说,使用std :: [w]字符串。至于行:
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());
}