Things to consider now that we are migrating to /clr:pure compilation:

  • Most of our heavy lifting is already done. We're now cleaning up everything that is invalid when running on a pure CLR setup, not just things that are invalid in C++. Unless I'm horribly mistaken, 100% of valid C++ is 100% of valid C++/CLI, except in very rare cases, none of which exist in the Q3 engine.
  • Varargs functions DO NOT WORK. The compiler tries to create unmanaged code, which creates all sorts of errors about calling across CLR/native boundaries.
  • HOWEVER! With exactly three exceptions (I'll get to those momentarily), the only places that functions with variable arguments exist in the entire codebase are printf-style strings.
    • Initial design was to use the C++/CLI syntax:
void Com_Printf(const char *msg, ...);

void Com_Printf(const char *msg, ... array<System::String ^> args);
  • However, it was quickly discovered that this led to constructs like:
Com_Printf("%i at %f (%s)", Int32(23).ToString(), Double(3.14).ToString(), gcnew String("foobar"));
  • Changing the definition to being an array of System::Object did little to rectify the situation. Therefore, I decided to eliminate these format strings entirely. This greatly reduces the impact on existing code, and allows new code to be written with purely managed types. From q_shared.h:
#define Q_StringFormat(x, ...) Q_CString(System::String::Format(gcnew String(x), __VA_ARGS__))
#define SF(x, ...) Q_StringFormat(x, __VA_ARGS__)
#define NS(x) gcnew String(x)

// example usage
Com_Printf("hello {0}!\nPI = {1}", NS("world"), 3.14);
  • Nice, isn't it? We also have a function to convert a string to a char array:
char *Q_CString(System::String^ in);
void Q_FreeCString(char *in);
  • You may notice that the macros don't call the free function. Sorry. I honestly don't know if the value returned from Q_CString() will be garbage-collected appropriately. TODO: check this on MSDN
  • The entirety of botlib has been converted to this usage. I believe I have removed all function declarations using the old vararg syntax, now all we need to do is convert the rest of the codebase.
  • The exceptions exist in the VM code. It exploits the compiler to blindly call between functions defined in different DLLs. This is bad and evil and hacky. I plan on fixing this by removing the entire VM subsystem and converting the APIs to work much like the botlib and renderer APIs. It's not very difficult work, just tedious. I should be able to copy+paste close to 100% of the required code from my engine.

Last edited Jan 12, 2009 at 12:59 AM by niteice, version 2


No comments yet.