我有一个自定义的插件对3d最大的接口与一些管理上的代码后面结束。在某些情况下,我想沿着管理对象为MAXScript为直接的互动,即返回的一个包裹对象从我的一个功能。

MAXScript是能够操纵的管理对象的直接比较好地通过另一个插件(msxdotNet)包括与Max(我采用3d Max2008年)。它基本上包的一个目的,并使用反映延迟开呼吁,但它是完全自给自足和没有任何sdk曝光。插件dll本身也不会让任何东西超过最低界面需要通过最大为增加一些高水平编写脚本课程。

照本宣科的课程能让一个实例新的对象,通过构造

local inst = (dotNetObject "MyPlugin.MyClass" 0 0 "arg3")

在我的情况下,我已经有对象的一个实例,我想到使用。

有没有一种方式建造的一个实例dotNetObject包装从我的插件返回到麦克斯?


理想,我想要有一个辅助职能(C++/CLI)签署类似的:

Value* WrapObject(System::Object ^obj);

一些基本保障,我可以使:

  • 该msxdotNet插件已经加载。
  • 该msxdotNet插件和我管理的集会都在相同的程序域.

源于msxdotNet插件 作为一个sdk样,但是对于管理/理智的缘故,修改和重新编译是不是一个选项。

有帮助吗?

解决方案

我已经解决了这个通过利用事实上,任何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倍,只要实际代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top