2011-09-10 12 views
4

관리 개체를 네이티브 함수로 보내면 어떻게 사용할 수 있습니까?관리 객체를 네이티브 함수로 보내면 어떻게 사용할 수 있습니까?

void managed_function() 
{ 
    Object^ obj = gcnew Object(); 

    void* ptr = obj ??? // How to convert Managed object to void*? 

    unmanaged_function(ptr); 
} 

// The parameter type should be void* and I can not change the type. 
// This function is native but it uses managed object. Because type of ptr could not be 
// Object^ I called it "Unmanaged Function". 
void unmanaged_function(void* ptr) 
{ 
    Object^ obj = ptr ??? // How to convert void* to Managed object? 

    obj->SomeManagedMethods(); 
} 
+1

그게 무슨 뜻 이죠? –

+3

함수가 네이티브 인 경우 관리되는 포인터에 대해 어떻게 알 수 있습니까? ('Object ^') –

+0

왜 COM을 사용하지 않습니까? –

답변

7

MSDN을 읽고 일부 코드를 시도한 후에이 방법을 사용하여 관리되는 개체를 관리되지 않는 기능에 전달했습니다.

이 메서드는 Object ^를 void *로 변환하고 void *를 Object ^로 변환하는 방법을 보여줍니다.

using namespace System; 
using namespace System::Runtime::InteropServices; 

void managed_function() 
{ 
    Object^ obj = gcnew Object(); 

    // Convert Object^ to void* 
    GCHandle handle = GCHandle::Alloc(obj); 
    IntPtr pointer = GCHandle::ToIntPtr(handle); 
    void* ptr = pointer.ToPointer(); 

    unmanaged_function(ptr); 

    handle.Free(); 
} 

void unmanaged_function(void* ptr) 
{ 
    // Convert void* to Object^ 
    IntPtr pointer(ptr); 
    GCHandle handle = GCHandle::FromIntPtr(pointer); 
    Object^ obj = (Object^)handle.Target; 

    obj->SomeManagedMethods(); 
} 

참고 : "unmanaged_function"에 가변 인수가 있으면이 방법이 작동하지 않습니다.

7

클리너와 더 나은 방법은 gcroot 템플릿을 사용하는 것입니다.

MSDN How to: Declare Handles in Native Types에서 인용 :

gcroot 템플릿이 값 클래스 시스템 :: 런타임 :: InteropServices :: GCHandle, 가비지 수집 힙로 "핸들"을 (를) 제공의 기능을 사용하여 구현됩니다 . 핸들 자체는 가비지 수집되지 않으며 gcroot 클래스의 소멸자가 더 이상 사용하지 않을 때 해제됩니다.이 소멸자는 수동으로 호출 할 수 없습니다. 네이티브 힙에서 gcroot 객체를 인스턴스화하는 경우 해당 자원에서 delete를 호출해야합니다.

귀하의 샘플 코드는 gcroot 사용하도록 (코드 컴파일을 2010 VS를 사용하여 실행) ".이 매개 변수는 * 무효가되어야하고 나는 형식을 변경할 수 없습니다"

using namespace System; 
using namespace System::Runtime::InteropServices; 

public ref class SomeManagedObject 
{ 
public: 
    String^ data; 
    SomeManagedObject() 
    { 
     data = "Initial Data"; 
    } 
    void SomeManagedMethods() 
    { 
     data = "Changed Data"; 
    } 
}; 

void unmanaged_function(void* ptr) 
{ 
    gcroot<SomeManagedObject^>& obj = *((gcroot<SomeManagedObject^>*)ptr); 
    obj->SomeManagedMethods(); 
} 

void managed_function() 
{ 
    // gcroot handles all allocations/deallocation and convertions 
    gcroot<SomeManagedObject^>* pObj = new gcroot<SomeManagedObject^>(); 

    *pObj = gcnew SomeManagedObject(); 
    unmanaged_function(pObj); 

    delete pObj; 
} 
+1

MWE의 경우 #include (적어도 VS14 afaik에서) –