我正在研究将现有的 Windows MFC 控件移植到 OS X/Carbon 的可行性。我的测试台是使用 XCode 3 向导生成的 C++ Carbon 应用程序。
我正在寻找一种将一些跟踪信息转储到调试器或 DbgView 的 OS X 等效项的快速方法。在 Win32 上,我会使用 OutputDebugString() - OS X 上的交易是什么?有没有办法查看从 Carbon 应用程序写入 std::cout 的测试?
谢谢
杰瑞
我正在研究将现有的 Windows MFC 控件移植到 OS X/Carbon 的可行性。我的测试台是使用 XCode 3 向导生成的 C++ Carbon 应用程序。
我正在寻找一种将一些跟踪信息转储到调试器或 DbgView 的 OS X 等效项的快速方法。在 Win32 上,我会使用 OutputDebugString() - OS X 上的交易是什么?有没有办法查看从 Carbon 应用程序写入 std::cout 的测试?
谢谢
杰瑞
没有真正的等价物。Xcode 在后台使用 GDB,因此您基本上是在处理它。但是,您可以自己实现它。仅当存在调试器时,下面的代码示例才会将输出输出到标准输出。如果在编译时存在 NDEBUG,您可以通过将其作为宏包装在预处理器指令中并编译出来(或编译成内联 nil 函数)来进一步保护它。应用程序产生的任何输出都将被定向到 Xcode 中的调试控制台。
extern "C" {
bool IsDebuggerPresent() {
int mib[4];
struct kinfo_proc info;
size_t size;
info.kp_proc.p_flag = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = getpid();
size = sizeof(info);
sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
return ((info.kp_proc.p_flag & P_TRACED) != 0);
}
void OutputDebugString(const char *restrict fmt, ...) {
if( !IsDebuggerPresent() )
return;
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
}
首先,Carbon 没有也不会提供 64 位版本。如果 Apple 放弃了 32 位 Mac OS X(可以肯定地认为迟早会发生),您的应用程序将无法运行。使用可可。
也就是说,有几种方法可以进行日志记录:
NSLog
这是一个 Cocoa 函数,但您也可以在 Carbon 应用程序中使用它。链接到 Foundation 框架,但不包含标题。自己声明:
int NSLog(CFStringRef format, ...);
您将传递一个 CFSTR 文字作为格式:
NSLog(CFSTR("Count: %u"), count);
NSLog 的优点是您可以使用 %@ 格式化程序打印 CF 属性列表对象(字符串、数据对象、日期、数字、数组和字典)。例如:
CFArrayRef array = /*...*/;
NSLog(CFSTR("Array: %@"), array);
printf/fprintf
旧的 C 标准库备用。#include <stdio.h>
得到他们。在 GUI 应用程序中并不重要,但您应该使用 stderr 来保持整洁:fprintf(stderr, "Count: %u\n", count);
系统日志
我猜大约和 f?printf 一样古老,但更强大。这是一个实际的日志系统,而不仅仅是写入文件。您可以指定诸如优先级之类的内容,允许您在 beta 测试人员的系统上抑制调试日志消息,同时仍然能够在您自己的系统上读取它们。(最终版本根本不应包含日志记录代码。)
asl_log
Part of Apple System Logger, Apple's more general replacement for syslog. I have a series of posts about ASL on my blog.
您可能想研究一下,syslog
因为它是基于 UNIX 系统的事实上的诊断方法。就像是:
#include <syslog.h>
/* Do this early on in your program like at the beginning of main() */
openlog("MYPROGRAM", 0, LOG_USER);
/* Use this to log something */
syslog(LOG_DEBUG, "%s %s", "Hello", "World");
/* Do this somewhere before you exit if you being are pedantic */
closelog();
谷歌系统日志了解更多信息。您还必须旋转一些位syslog.conf
以将输出定向到日志或控制台。然后您可以在终端窗口或使用控制台应用程序查看输出。
在 Xcode 中,您可以在“控制台”窗口 (Run->Console)中看到std::cout
/的输出。std::cerr
还有 Console.app(在 /Applications/Utilities 中),它记录std::cerr
从 GUI 应用程序写入的所有输出。