Custom 3DS Max 플러그인에서 dotnetobject 값을 반환하는 방법이 있습니까?

StackOverflow https://stackoverflow.com/questions/421566

  •  05-07-2019
  •  | 
  •  

문제

백엔드의 일부 관리 코드와 인터페이스하는 3DS MAX 용 사용자 정의 플러그인이 있습니다. 어떤 상황에서는 직접 상호 작용을 위해 관리되는 객체를 따라 MaxScript로 전달하고 싶습니다. 즉, 내 함수 중 하나에서 랩핑 된 객체를 반환합니다.

MaxScript는 Max (3ds Max 2008을 사용하고 있음)에 포함 된 다른 플러그인 (MSXDOTNET)을 통해 관리 된 객체를 비교적 잘 조작 할 수 있습니다. 기본적으로 물체를 감싸고 늦은 바운드 호출에 반사를 사용하지만 완전히 자체적으로 포함되어 있으며 SDK 노출이 없습니다. 플러그인 DLL 자체는 몇 가지 최상위 스크립트 클래스를 추가하기 위해 Max가 요구하는 최소 인터페이스 이상의 것을 노출시키지 않습니다.

스크립트 클래스는 하나가 생성자를 통해 새 개체를 인스턴스화 할 수 있도록합니다.

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

제 경우에는 이미 사용하고 싶은 객체의 인스턴스가 있습니다.

내 플러그인 내에서 DotNetObject 래퍼 인스턴스를 MAX로 돌아갈 수있는 방법이 있습니까?


아이디어적으로, 나는 다음과 유사한 (c ++/cli) 서명으로 도우미 기능을 원합니다.

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

내가 할 수있는 몇 가지 기본 보증 :

  • MSXDOTNET 플러그인이 이미로드되었습니다.
  • MSXDOTNET 플러그인과 관리 조립품은 동일한 appDomain에 있습니다.

MSXDOTNET 플러그인 소스 ~이다 SDK 샘플로 포함되지만 관리/Sanity를 위해 수정하고 다시 컴파일하는 것은 옵션이 아닙니다.

도움이 되었습니까?

해결책

DotNetObject로 포장 된 모든 CLR 객체가 다른 래퍼와 함께 반환 값 (메소드 결과 및 속성 값)을 자동으로 래핑한다는 사실을 활용하여이를 해결했습니다. 이는 DotNetClass로 포장 된 CLR 유형의 정적 메소드 및 속성에도 적용됩니다.

플러그인에 이미 임의의 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