2013-05-09 3 views
0

.NetCF3.5를 사용하고 P/Invoke를 사용하여 여러 개의 기본 C++ DLL을 인터페이스하는 CE6.0R3 시스템이 있습니다.핸들을 원시 코드로 사용할 수 있도록 GCHandle.Alloc()에 양식을 고정하는 데 문제가 발생했습니다.

이러한 장치는 때때로 비정상적으로 종료되며 "Application myC# app.exe에서 심각한 오류가 발생하여 종료해야합니다"라는 팝업이 표시되는 경우가 있습니다.

우리가하는 일 중 하나는 C# 형식의 핸들을 DirectShow를 사용하여 C# 형식으로 비디오를 렌더링하는 네이티브 C++ 응용 프로그램에 전달하는 것입니다.

저는 GCHandle을 사용하여 관리 대상을 고정시켜 움직이지 않도록 여러 가지 토론을했습니다.

문제가있는 경우 진단하고 GCHandle.Alloc()를 추가하여 객체를 고정하는 진단 기능을 추가했습니다. 어떤 이유로 개체가 고정되어야하더라도 메모리에서 움직이는 것처럼 보입니다.

Diag.Putline("_videoplay create"); 
_videoplay = new Form(); 

Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before pinning Handle"); 
GCHandle gch = GCHandle.Alloc(_videoplay.Handle, GCHandleType.Pinned); 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before pinning Form"); 
GCHandle gch_videoplay = GCHandle.Alloc(_videoplay, GCHandleType.Pinned); // Pin the _videoplay object instance so it won't get moved by GC 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " after pinning"); 

Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before .Location"); 
_videoplay.Location = new Point(x, y); 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before .Size"); 
_videoplay.Size = new Size(w, h); 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before .BackColor"); 
_videoplay.BackColor = bgColor; 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before .FormBorderStyle"); 
_videoplay.FormBorderStyle = FormBorderStyle.None; 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before .Owner"); 
_videoplay.Owner = _mediaform; 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before .Show()"); 
_videoplay.Show(); 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " after .Show()"); 

Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " before directshow_connect"); 
Diag.Putline("directshow_connect"); 

// P/Invoke to our native C++ application based on this code: http://msdn.microsoft.com/en-us/library/ms899491.aspx 
// Pass the handle ot our form that we want to display the video on 
// the directshow HWND will be a WS_CHILD of _videoplay 
directshow_connect(_videoplay.Handle); 
Diag.Putline("_videoplay.Handle = " + _videoplay.Handle + " after directshow_connect"); 

그리고 출력 : 왜 핸들 변화가

14:59:37| _videoplay create 
14:59:37| _videoplay.Handle = 1879191552 before pinning Handle 
14:59:37| _videoplay.Handle = 1879191552 before pinning Form 
14:59:37| _videoplay.Handle = 1879191552 after pinning 
14:59:37| _videoplay.Handle = 1879191552 before .Location 
14:59:37| _videoplay.Handle = 1879191552 before .Size 
14:59:37| _videoplay.Handle = 1879191552 before .BackColor 
14:59:37| _videoplay.Handle = 1879191552 before .FormBorderStyle 
14:59:37| _videoplay.Handle = 1879191776 before .Owner 
14:59:37| _videoplay.Handle = 1879192000 before .Show() 
14:59:37| _videoplay.Handle = 1879192000 after .Show() 
14:59:37| _videoplay.Handle = 1879192000 before directshow_connect 
14:59:37| directshow_connect 
14:59:39| _videoplay.Handle = 1879192000 after directshow_connect 
14:59:41| _videoplay.Handle = 1879193248 (_TickTockThreadProc) 
14:59:41| _videoplay.Handle = 1879193248 (_TickTockThreadProc) 
14:59:41| _videoplay.Handle = 1879193248 (UpdateTimer_Tick) 
14:59:41| _videoplay.Handle = 1879193248 (UpdateTimer_Tick) 
14:59:41| _videoplay.Handle = 1879193248 (_TickTockThreadProc) 
14:59:42| _videoplay.Handle = 1879193248 (_TickTockThreadProc) 

을 고정됩니다 않더라도 여기

는 내 코드의 부분입니까?

답변

2

GCHandle의 작동 원리와 사용법을 잘못 이해합니다.

먼저 GCHandle은 blittable 형식에서만 사용할 수 있으므로 Form 자체를 고정 할 수는 없습니다. 당신이하고있는 일은 핸들을 고정하는 것입니다. 핸들은 기본적으로 GC의 "메모리에있는 폼의 주소가있는 위치를 이동하지 마십시오"라고 말합니다. 핸들 자체의 저장 위치를 ​​이동할 수 없음을 의미합니다. Form이 이동하는 것을 막을 수있는 것은 없으므로 Handle이 유지하는 값인이 입니다.

핸들이 변경되는 것이 약간 이상합니다. 양식 자체가 만들어지면 네이티브 형식 핸들 자체를 변경할 수 없다고 생각됩니다. 그게 네가 의사 처리를했다고 생각하게 만든다. 그렇다면 네이티브 호출에서이 함수를 사용하면 안됩니다.

이전에 그런 행동을 한 번도 본적이 없기 때문에 오류가 운동이라고 확신하지는 않습니다. 삭제 된 양식의 핸들을 사용하려는 시도라고 생각하는 경향이 있지만 디버깅을하고 더 나은 느낌을 가질 수 있습니다.

어쨌든 오류가 핸들 변경으로 인한 것일 경우 가장 좋은 해결 방법은 P/Invoke (CreateWindowEx에)를 사용하여 컨테이너 양식 자체를 만드는 것입니다. GC는 그것에 대해 아무 것도 모르기 때문에 그 다음 이동할 수 없습니다. 그것은 범인으로서의 압박을 제거 할 것입니다 (또는 문제를 해결하십시오).