OS X equivalente a OutputDebugString ()?
-
03-07-2019 - |
Domanda
Sto esaminando la fattibilità del porting di un controllo MFC Windows esistente su OS X / Carbon. Il mio banco di prova è un'applicazione Carbon C ++ generata utilizzando la procedura guidata XCode 3.
Sto cercando un modo rapido per scaricare alcune informazioni di traccia sul debugger o sull'equivalente OS X di DbgView. Su Win32 userei OutputDebugString () - qual è il problema su OS X? Esiste un modo per visualizzare i test scritti su std :: cout da un'app Carbon?
Grazie
Jerry
Soluzione
Non esiste un equivalente reale. Xcode utilizza GDB sotto il cofano, quindi in pratica ne hai a che fare. Tuttavia, potresti implementarlo da solo. L'esempio di codice seguente produrrà l'output allo standard out solo quando è presente il debugger. È possibile proteggerlo ulteriormente avvolgendolo nelle direttive del preprocessore come macro e compilarlo (o in una funzione nulla inline) se NDEBUG è presente al momento della compilazione. Qualsiasi output prodotto da un'applicazione verrà indirizzato alla console di debug in 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);
}
}
Altri suggerimenti
Prima di tutto, Carbon non è e non sarà disponibile a 64 bit. Se Apple non rilascia mai Mac OS X a 32 bit (che è sicuro supporre accadrà prima o poi), la tua app non verrà eseguita. Usa il cacao.
Detto questo, ci sono diversi modi per effettuare la registrazione:
-
NSLog
Questa è una funzione Cocoa, ma puoi usarla anche nelle app Carbon. Collegamento al framework Foundation, ma non includere l'intestazione. Dichiaralo tu stesso:
int NSLog(CFStringRef format, ...);
Passerai un letterale CFSTR come formato:
NSLog(CFSTR("Count: %u"), count);
Il vantaggio di NSLog è che è possibile stampare oggetti dell'elenco di proprietà CF (stringhe, oggetti dati, date, numeri, matrici e dizionari) utilizzando% @ formatter. Ad esempio:
CFArrayRef array = /*...*/; NSLog(CFSTR("Array: %@"), array);
-
printf / fprintf
I vecchi standbys della libreria standard C.
#include <stdio.h>
per ottenerli. Non importa molto in un'app GUI, ma dovresti usare stderr per la pulizia:fprintf(stderr, "Count: %u\n", count);
-
syslog
Probabilmente vecchio quanto f? printf, ma più potente. Questo è un vero sistema di registrazione , non solo scrivere su un file. Puoi specificare cose come la priorità, permettendoti di sopprimere i tuoi messaggi di log di debug sui sistemi dei beta tester pur continuando a leggerli sul tuo sistema. (Le versioni finali non devono contenere affatto codice di registrazione.)
-
asl_log
Parte di Apple System Logger, la sostituzione più generale di Apple per syslog. Ho una serie di post su ASL sul mio blog.
Potresti voler esaminare syslog
poiché è il metodo diagnostico di fatto sui sistemi basati su UNIX. Qualcosa del tipo:
#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();
Google syslog per ulteriori informazioni. Dovrai anche modificare alcuni bit in syslog.conf
per indirizzare l'output a un registro o una console. Quindi è possibile visualizzare l'output in una finestra del terminale o utilizzando l'applicazione Console.
In Xcode puoi vedere l'output di std::cout
/ std::cerr
nella " console " finestra (Esegui - > Console).
Esiste anche Console.app (in / Applicazioni / Utility) che registra tutto l'output scritto in <=> dalle applicazioni della GUI.