- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 Qt 编写一个 GUI 应用程序,它链接到有时会向 stderr 发送错误消息的第三方 DLL。我希望这些错误消息显示在我的 GUI 中的一个窗口中。
即使经过大量搜索,我也找不到重定向 stderr(与 std::cerr 相对)的既定方法,所以我自己编写了以下类:
class StdErrRedirect : public QObject
{
Q_OBJECT
public:
// Constructor
StdErrRedirect(QTextEdit *errorLog,
QObject *parent = NULL);
// Destructor
~StdErrRedirect();
private slots:
void fileChanged(const QString &filename);
private:
QFile tmp;
QFileSystemWatcher watcher;
QString tmpFileNameQtFormat;
QString tmpFileNameNativeFormat;
QTextEdit *m_errorLog;
QString oldContent;
};
StdErrRedirect::StdErrRedirect(QTextEdit *errorLog,
QObject *parent)
: QObject(parent)
{
// Store the pointer to the error log window
m_errorLog = errorLog;
// Create a temporary filename: first find the path:
tmpFileNameQtFormat = QDir::tempPath();
// Make sure the closing slash is present:
if (!tmpFileNameQtFormat.endsWith(QChar('/')))
tmpFileNameQtFormat.append(QChar('/'));
// Add the file name itself:
tmpFileNameQtFormat.append("nb_stderrlog");
// Obtain a version of the filename in the operating system's native format:
tmpFileNameNativeFormat = QDir::toNativeSeparators(tmpFileNameQtFormat);
// Set up redirection to this file:
freopen(tmpFileNameNativeFormat.toAscii().constData(), "a+", stderr);
// Initialise the QFileSystemWatcher:
connect(&watcher, SIGNAL(fileChanged(const QString &)),
this, SLOT(fileChanged(const QString &)));
watcher.addPath(tmpFileNameQtFormat);
tmp.setFileName(tmpFileNameQtFormat);
}
StdErrRedirect::~StdErrRedirect()
{
// Ensure the temporary file is properly deleted:
fclose(stderr);
tmp.close();
tmp.open(QIODevice::ReadWrite);
tmp.remove();
}
void StdErrRedirect::fileChanged(const QString &filename)
{
tmp.open(QIODevice::ReadOnly);
QTextStream stream(&tmp);
QString content = stream.readAll();
tmp.close();
// Identify what's new, and just send this to the window:
int newchars = content.size() - oldContent.size();
if (newchars)
{
m_errorLog -> append(content.right(newchars));
oldContent = content;
}
}
如果我使用以下方法从我的主窗口实例化它:
errorLog = new QTextEdit;
redirector = new StdErrRedirect(errorLog);
...然后我写入 stderr 的所有内容都会出现在窗口中。
到目前为止,还不错。问题是 DLL 的输出仍然没有。在对发出错误的 DLL 函数的调用中,如果我输入代码:
if (error != _OK)
{
error.PrintErrorTrace();
fprintf(stderr, "Should have printed an error \r\n");
fflush(stderr);
//fsync(_fileno(stderr)); Linux version
_commit(_fileno(stderr));
return;
}
...然后出现文本“应该打印错误”,但错误消息本身不会出现。
现在,我在某处读到这可能是因为在应用程序开始时加载 DLL 之后正在设置重定向,因此它自己的 stderr channel 不受影响。因此,我应该能够通过动态加载 DLL 来修复此问题,在设置重定向之后。
那么这是我的问题:我该怎么做?我可以尝试将以下代码放在我的应用程序的开头:
QLibrary extlib;
extlib.setFileName("libname");
extlib.setLoadHints(QLibrary::ResolveAllSymbolsHint);
extlib.load();
...但它本身没有任何效果。我认为这是因为链接器仍在将库设置为自动打开。但是,如果我从链接器中删除 DLL(我使用的是 VS2008,因此我从依赖项列表中删除了 extlib.lib),那么应用程序将无法编译,因为编译器无法从 DLL 中找到符号。
所以我在这里尝试做的事情显然存在严重错误。有人可以帮忙吗?
谢谢,斯蒂芬。
最佳答案
DLL 是否真的写入了stderr
?还是写入 GetStdHandle(STD_ERROR_HANDLE)
?第一个映射到第二个,最初。但是使用 freopen()
您只需更改映射。写入 STD_ERROR_HANDLE
的任何内容仍会保留在那里。
要重定向每个人的错误输出,您需要 SetStdHandle
.
关于c++ - 加载 DLL 是否会动态协调其 stderr 到主应用程序?如果是这样,那么如何......?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3202654/
我听说过两种数据库架构。 大师级 主从 master-master不是更适合现在的web吗,因为它就像Git一样,每个单元都有整套数据,如果一个宕机也无所谓。 主从让我想起了 SVN(我不喜欢它),你
我们当前将 MySQL 配置为支持故障转移:Site1 Site2。当它们被设置为主/主时。在给定时间点,应用程序服务器仅主动写入一个站点。我们想要设置一个新的故障转移站点。然后我们将拥有 Site
我听说过两种数据库架构。 大师-大师 主从 master-master 不是更适合当今的网络吗,因为它就像 Git,每个单元都有整套数据,如果其中一个发生故障,也没关系。 主从让我想起 SVN(我不喜
我正在创建一个标记为类别的表,其中主类别(父列)包含 0,子类别包含父类别的 ID。我听说这叫引用。我的问题:这张表的结构正确吗?或者是否有更好的方法,例如实现遍历树或类似方法? CREATE TAB
我正在阅读一份关于 C++ 与 C 的文档。该文档说与 C 相比,C++ 编写得非常紧凑。一个例子是,C 允许 main() 函数类型为 void。另一方面,C++ 不允许这样做,他给出了标准中的以下
C main函数和Java main函数有什么区别? int main( int argc, const char* argv[] ) 对比 public static void main(Strin
我一直摸不着头脑,但运气不好。设计器有一个包含 3 栏的站点、两个侧边栏和一个主要内容区域。 专为桌面设计,左栏、主要内容、右栏。但是,在较小的设备上,我们希望首先堆叠主要内容。 所以通常情况下,你可
我一直在阅读有关 Jenkins 主/从配置的信息,但我仍然有一些问题: 是不是真的没有像 Jenkins 主站那样安装和启动从站 Jenkins?我假设我会以相同的方式安装一个主 Jenkins 和
据我了解,Viemodel中MVVM背后的概念包括业务逻辑和/或诸如暴露于 View 的数据的主/明细关系之类的事物 因此,正如我发现的那样,有很多ORM生成器,例如模型的telerik a.o以及另
我们有一个群集,其中包含3个主分区,每个主分区有2个副本。主/副本分片的总文档数相同;但是,对于同一查询/文档,我们得到3个不同的分数。当我们将preference = primary添加为查询参数时
我有一个非常大/旧/长时间运行的项目,它使用相对于启动目录的路径访问文件资源(即应用程序仅在从特定目录启动时才工作)。当我需要调试程序时,我可以从 eclipse 启动它并使用“运行配置”->->“工
谁能向我解释一下为什么我在这段代码上遇到段错误?我一直试图弄清楚这一点,但在各种搜索中却一无所获。当我运行代码而不调用 main(argc, argv) 时,它会运行。 Slave 仅将 argv 中
使用 xcode 中的默认项目作为主从应用程序,如果我在折叠委托(delegate)中放置 print 调试语句,当我旋转设备时它似乎永远不会被触发(事实上我永远无法触发它)。 我编辑的代码位于 Ap
是否有任何产品可以使 mysql 主/从故障转移过程更容易?一些可以自动发生的事情,而不是手动修复它。 最佳答案 [...稍后...;) 你所说的“更容易”是什么?MySQL 有很多解决方案: MyS
我有两个 mysql 数据库。我想做主/主复制。 复制以一种方式进行。然而,反过来说却不然。该错误表明它无法与用户“test@IPADDRESS”连接。 如何将用户名更改为 repl?从未进行过测试,
我正在尝试在 MySQL 中运行以下查询: GRANT REPLICATION SLAVE ON *.* TO 'replication'@’10.141.2.%’ IDENTIFIED BY ‘sl
我正在尝试使用 Android 提供的主/详细流程模板创建一个应用程序,并且我正在尝试将多个操作栏菜单项添加到操作栏的主要部分和详细信息部分。这就是我要实现的目标: (来源:softwarecrew.
我正在寻找一个跨平台的 C++ master/worker 库或工作队列库。一般的想法是我的应用程序将创建某种任务或工作对象,将它们传递给工作主机或工作队列,这将依次在单独的线程或进程中执行工作。为了
我似乎看到很多人在他们的 MySQL 模式中任意分配大尺寸的主/外键字段,例如 INT(11) 甚至 WordPress 使用的 BIGINT(20)。 如果我错了,请纠正我,但即使是 INT(4)
如果我有一个可以与多个键相关联的用户,正确的表设置应该是: 一个表有两列,例如: UserName | Key 没有主键且用户可以有多行,或者: 具有匹配标识符的两个表 Table 1 Us
我是一名优秀的程序员,十分优秀!