The current (3.2.3) windows binary distribution is missing mono-2.0.dll
, so it must be build from source.
Get Mono source
Using Cygwin, follow these instructions
"configure: error: msgfmt not found. You need to install the 'gettext' package, or pass --enable-nls=no to configure." Need cygwin package gettext-devel and probably gettext too.
PEXECUTION_STATE redefined with different type. Change typedef PVOID PEXECUTION_STATE;
to typedef PDWORD PEXECUTION_STATE;
in C:\cygwin\usr\i686-pc-mingw32\sys-root\mingw\include\ddk\ntapi.h
machine.config permission error. Change the permission to read/write.
The missing "mono-2.0.dll" will be in "mono\mini.libs", rename either libmonosgen-2.0.dll
or libmonoboehm-2.0.dll
, depending on which GC you want.
Error checking omitted for briefness.
static const char *GetStringProperty(const char *propertyName, MonoClass *classType, MonoObject *classObject)
{
MonoProperty *messageProperty;
MonoMethod *messageGetter;
MonoString *messageString;
messageProperty = mono_class_get_property_from_name(classType, propertyName);
messageGetter = mono_property_get_get_method(messageProperty);
messageString = (MonoString *)mono_runtime_invoke(messageGetter, classObject, NULL, NULL);
return mono_string_to_utf8(messageString);
}
MonoObject *exceptionObject = NULL;
returnObject = mono_runtime_invoke(method, classObject, args, &exceptionObject);
if (exceptionObject)
{
MonoClass *exceptionClass;
MonoType *exceptionType;
const char *typeName, *message, *source, *stackTrace;
exceptionClass = mono_object_get_class(exceptionObject);
exceptionType = mono_class_get_type(exceptionClass);
typeName = mono_type_get_name(exceptionType);
message = GetStringProperty("Message", exceptionClass, exceptionObject);
source = GetStringProperty("Source", exceptionClass, exceptionObject);
stackTrace = GetStringProperty("StackTrace", exceptionClass, exceptionObject);
}
Or just use the _MonoException
struct in metadata/object-internals.h
If using unmanaged thunks, cast MonoException *
to MonoObject *
to call mono_object_get_class
.
Call mono_debug_init(MONO_DEBUG_FORMAT_MONO);
If building with Visual Studio, pdb files must to converted to mdb (Mono format). See here. This is easiest done as a post build step. If Mono is in the PATH environment variable, it's as simple as pdb2mdb "$(TargetPath)"
. Note that pdb2mdb takes the assembly name as a parameter, expects assembly.pdb
to be in the same directory, and outputs assembly.dll.mdb
not assembly.mdb
.
The best documentation is in mono/metadata/object.c
To access raw struct/class data from a MonoObject *
:
typedef struct
{
int id
MonoString *name;
MonoBoolean enabled;
}
MyStruct;
static void MyInternalCallFunction(MonoObject *object)
{
const MyStruct *myStruct = (const MyStruct *)((uint8_t *)object + sizeof(MonoObject));
}
C# classes must use [StructLayout(LayoutKind.Sequential)]
, data structures must match etc.