//非单身人士 类MyLogManager { void write(message){Ogre :: LogManager :: getSingletonPtr() - > logMessage(message);} }
class Utils : public singleton<Utils>
{
MyLogManager *handle;
MyLogManager& getHandle { return *handle; }
};
namespace someNamespace
{
MyLogManager &Log() { return Utils::get_mutable_instance().getHandle(); }
}
int main()
{
someNamespace::Log().write("Starting game initializating...");
}
在这段代码中,我使用boost的单例(来自序列化)并调用Ogre的日志管理器(它也是单例类型)。
程序在尝试使用代码
Ogre :: LogManager :: getSingletonPtr()对象时无效 User program stopped by signal (SIGSEGV)
我检查 getSingletonPtr()返回地址 0x000
但是使用代码Utils::get_mutable_instance().getHandle().write("foo")
在程序的另一部分中效果很好。打电话给单身者会有什么不对?
Utils类的真实版本:
class Utils : public singleton<Utils>
{
protected:
ConfigManager *configHandlePtr;
LogManager *logHandlePtr;
public:
Utils()
{
configHandlePtr = new ConfigManager();
string engineLog = configHandle().getValue<string>("engine.logFilename", "Engine.log");
logHandlePtr = new LogManager(engineLog);
}
~Utils()
{
delete configHandlePtr;
delete logHandlePtr;
}
ConfigManager &configHandle() const { return *configHandlePtr; }
LogManager &logHandle() const { return *logHandlePtr; }
};
以下是 LogManager 类的实际代码:
class LogManager
{
protected:
string mDefaultPath;
public:
LogManager(const string &logPath = "Engine.log") :
mDefaultPath(logPath) { }
void write(const string &message, const string logFile = "")
{
string workPath = mDefaultPath;
Ogre::LogManager *logHandle = Ogre::LogManager::getSingletonPtr(); // [logHandle=0x000]
Ogre::Log *log2Handle = logHandle->getLog(workPath); // [SEGFAULT]
log2Handle->logMessage(message);
Ogre::LogManager::getSingletonPtr()->logMessage(message);
}
};
更新
我有一个静态库(有我的引擎代码)和主要自己的程序,它链接静态这个库。当我调用我的配置句柄(不使用Ogre)时,一切都还可以!还有 resourceManager ,它也使用Ogre。它像 logManager 一样失败。这两位经理都使用Ogre的单身人士。也许从另一个图书馆调用它是不可能的?
答案 0 :(得分:1)
感觉就像你有典型的“static initialization order fiasco” - 你的Utils实例在一个(或两个)其他单身人士之前创建。
尝试将Utils :: configHandle()更改为以下内容:
ConfigManager &configHandle() const {
static std::auto_ptr<ConfigManager> configHandlePtr(0);
if (!configHandlePtr.get()) {
configHandlePtr.reset(new ConfigManager());
// init configHandlePtr like you want
}
return *configHandlePtr;
}
答案 1 :(得分:0)
我不知道Boost的单身人士,但我注意到你的'Utils'课上有些奇怪的东西。
首先,getHandle返回对handle的引用,但是如果你离开方法,handle是一个超出范围的局部变量,因此对它的引用也将无效。
其次,你没有在getHandle方法中初始化句柄。
答案 2 :(得分:0)
您确定您的Ogre LogManager已正确初始化吗?
或者你的库可能在每个库中都有一个单例实例,只有主程序中的一个实例被正确初始化了?
在这种情况下,您必须将库中的单例声明为“extern”,但我不确定它是否适用于静态链接库。