Я решил это, используя тот факт, что любой объект CLR, обернутый dotNetObject, будет автоматически переносить возвращаемые значения (результаты метода и значения свойств) с помощью другой оболочки. Это относится даже к статическим методам и свойствам типов CLR, заключенных в dotNetClass.
Допустим, у меня уже есть метод в моем плагине, который позволяет мне выполнять произвольный MAXScript:
Value* EvalScript(System::String ^script);
Теперь мне просто нужно сериализовать объект в строку и вернуться обратно к активному объекту (ссылка на тот же объект, а не просто копия!).
Я делаю это, захватывая GCHandle
объекта, используя GCHandle::ToIntPtr
, чтобы преобразовать его во что-то легкое, и используя GCHandle::FromIntPtr
, чтобы материализовать тот же объект в другом контексте. Конечно, я делаю это в процессе (и в том же домене приложения), иначе это не сработает.
Value* WrapObject(System::Object ^obj)
{
GCHandle handle = GCHandle::Alloc(obj)
try
{
return EvalScript(System::String::Format(
L"((dotNetClass \"System.Runtime.InteropServices.GCHandle\").FromIntPtr (dotNetObject \"System.IntPtr\" {0})).get_Target()",
GCHandle::ToIntPtr(handle));
}
finally
{
handle.Free();
}
}
Комментарий, который я объяснил в реальном коде, более чем в 10 раз превосходит фактический код.