2011-11-20 3 views
6

나는 (http://msdn.microsoft.com/en-us/library/windows/desktop/aa381866(v=vs.85).aspx에 정의 된) ITaskTrigger :: GetTriggerString 메서드의 pinvoke를 쓰려고합니다. 이 페이지를 보면 메서드의 호출자가 첫 번째 인수를 통해 참조 된 LPWSTR의 메모리를 CoTaskMemFree를 통해 해제하는 작업을 담당한다고합니다. NET에서 수동으로 할 수 또는 ICustomMarshaler를 사용하여 내 사용자 지정 마샬 러 쓸 수 있지만 해당 특정 인수에 대한 MarshalAs (UnmanagedType.LPWStr) 특성을 사용하여 메모리를 적절하게 해제됩니다 궁금 해서요.MarshalAs (UnmanagedType.LPWStr) 정리 메모리를 사용합니까?

누구나 통찰력을 제공 할 수 있습니까?

+0

COM Interop를 사용하여 동적 유형 작업을 살펴보십시오. 이렇게하면 정적 유형보다 훨씬 쉽게 작업 할 수 있으며 메모리 관리도 처리합니다. – weismat

+0

마지막 비트에 대한 참조가 있습니까? C#은 이미 COM interop에 대한 메모리 관리를 수행하며 항상 가지고 있습니다. 동적 유형은 예를 들어 IDispatch 인터페이스를 처리 할 때 작업을 더 쉽게 해주지 만 실제로 정적 interop 유형과는 다른 메모리 관리 기능을 가지고 있습니까? –

답변

6

먼저 COM Interop에 대해 얘기하고 있습니다 (ITaskTrigger은 COM 인터페이스 임). P/Invoke가 아닙니다. 두 가지에 대한 서로 다른 interop 규칙이 있으므로이를 그대로 유지하는 것이 중요합니다. 예를 들어 원하는 메서드뿐만 아니라 전체 인터페이스에 대해 C# interop 래퍼를 정의해야합니다. 다음과 같이 시작해야합니다. pinvoke.net

CLR이 올바르게 처리해야하기 때문에 짧은 응답입니다.

답변이 길수록 매개 변수 유형, 방향 및 interop 시그니처에 추가하는 특성에 따라 COM interop 코드의 마샬링 유형이 다릅니다.

이 경우 호출 할 매개 변수 유형은 out string이며 MarshalAs(UnmanagedType.LPWSTR) 속성입니다. COM 서버가 LPWSTR 문자열 형식의 "out"매개 변수를 가진 호출을 노출하면 서버가 거래의 끝을 유지한다고 가정하면 CoTaskMemAlloc()과 함께 메모리 버퍼를 할당하고 반환합니다. (다른 문자열 유형 인 BSTR과 같은 경우 특정 메모리 할당 호출은 다를 수 있지만 기본 개념은 동일합니다.) 이제는 더 이상 필요하지 않을 때 메모리를 정리해야합니다. 일치하는 CoTaskMemFree() 호출을 사용합니다.

이것은 "참조 변화"라는 동작의 특별한 유형 : 당신이 보내는 매개 변수가 이미 참조 매개 변수이지만, COM 서버가 다른 참조 교체 을 것입니다. 이 프로세스에 대한 좋은 설명은 this MSDN magazine article의 "메모리 소유권"섹션에 나와 있습니다. 이 기사에서 알 수 있듯이 CLR이 참조 형식의 "out"매개 변수에서 데이터를 받으면 해당 메모리를 해제 할 책임이 있음을 인식합니다. 해당 호출을 관리되는 코드로 마샬링하는 동안 MarshalAs 특성을 사용하여 COM에서 LPWSTR 문자열 형식 포인터인지 확인하고 따라서 CoTaskMemAlloc()을 사용하여 할당해야합니다. 데이터에서 관리되는 문자열을 만든 후에는 사용자를 대신하여 원래 버퍼에 CoTaskMemFree()을 호출합니다. 다시 가져온 데이터는 완벽하게 관리되므로 소유권 문제를 해결할 필요가 없습니다.

+1

답변 해 주셔서 감사합니다! 그것은 그것을 완벽하게 분명하게합니다. – wwahammy

+1

정말 좋은 설명, 고마워. –

관련 문제