Click to See Complete Forum and Search --> : printf in a managed wrapper


Toot
November 23rd, 2005, 06:00 AM
Hi all,

I'm writing a managed wrapper so my c# clients can play with some low-level shared libraries.

I'm including all the C++ source files and writing managed classes that create unmanaged objects and convert things into managed objects appropriately.

It has been working really well until I started getting complex. My unmanaged source uses a macro several million times
TCI_DEBUG(TCI_DEBUG_INFORMATION,("TCI_measurements(%d, %x)\n", engine_number, configuration));
defined as
#define TCI_DEBUG(level,result) if (level >= TCI_DEBUG_LEVEL) printf result
Clearly that's fine in the OS9 or VS6 win32 world but printf isn't available in my managed library (and I don't want it to be).

So I need to re-define the TCI_DEBUG macro and that's where I'm having trouble. First, I tried
#define TCI_DEBUG(level, result) if (level >= TCI_DEBUG_LEVEL) Debug::WriteLine(String::Format result)
but as soon as I called
int i = 7;
TCI_DEBUG(TCI_DEBUG_ALL, ("foo bar %d\n", i));
I get error C2665:
error C2665: 'System::String::Format' : none of the 5 overloads can convert parameter 2 from type 'int'
stdafx.cpp(0): could be 'System::String __gc *System::String::Format(System::String __gc *,System::Object __gc *)'
stdafx.cpp(0): or 'System::String __gc *System::String::Format(System::String __gc *,System::Object __gc * __gc[])'
while trying to match the argument list '(const char [12], int)'

So then I tried defining my own printf function which calls snprintf to format the string, with the hope of then passing that to Debug::WriteLine, but I can't get the hang of the va_start syntax and how to use it when just passing params on...
void myprintf(const char* format, ...)
{
va_list arg_list;
char buff[255];

va_start(arg_list, format);
_snprintf(buff, 255, format, arg_list);
}

(and several thousand other attempts).

Can anyone help? Either with the printf redefinition or another suitable path?

Thanks for your time, whether you can or not.
T

Alex F
November 23rd, 2005, 10:12 AM
Debug::WriteLine(String::Format result)

I am not sure that I understand this macro, but compiler message is clear: int type cannot be converted to Object*. You need to use boxing for this conversion (__box).

NoHero
November 23rd, 2005, 12:19 PM
void Log ( String *Message, int Code )
{
String *str = String::Format(S"log >> {0}; code: {1}", Message, __box(Code));
Console::WriteLine(str);
}

Should do the trick. Any value types (including e.g. all POD's) must be boxed to be used with String::Format().