성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>.NET COM+ 를 Managed/Native 클라이언트에서 각각 호출했을 때의 콜 스택 비교</h1> <p> <br /> 우선, 테스트 환경을 구성해 볼까요? ^^<br /> <br /> C#으로 서버 유형의 COM+ 코드를 다음과 같이 만들어 줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [GuidAttribute("0C0445BE-A12E-4DE4-A022-156EF491989D")] [ClassInterface(ClassInterfaceType.AutoDual)] public class MyClass : System.EnterpriseServices.ServicedComponent { public object DoIt() { System.Diagnostics.Trace.WriteLine(Environment.StackTrace); return "test"; } } [assembly: ApplicationAccessControl(false)] [assembly: ApplicationActivation(ActivationOption.Server)] [assembly: ApplicationName("TestRDS")] [assembly: ApplicationID("727FC170-1D80-4e89-84CC-22AAB10A6F24")] [assembly: ComVisible(true)] </pre> <br /> 그리고, C# 으로 해당 COM+ 를 호출하는 코드를 (관리자 권한으로) 불러주면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > class Program { static void Main(string[] args) { TestCOMObj.MyClass mc = new TestCOMObj.MyClass(); Console.WriteLine(mc.DoIt()); } } </pre> <br /> COM+ 구성요소 서비스에 새롭게 COM+ 응용 프로그램이 생성된 것을 볼 수 있습니다.<br /> <br /> 자, 이제 Visual Studio 의 "Attach to process..." 기능을 이용해서 실행 중인 COM+ exe 개체에 디버거를 연결한 후, DoIt 메서드에 중단점을 잡고 C# 클라이언트를 다시 호출해 주면 다음과 같은 콜 스택이 확인됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > TestCOMObj.dll!TestCOMObj.MyClass.DoIt() Line 18 C# [Native to Managed Transition] [Managed to Native Transition] mscorlib.dll!System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(...[생략]...) + 0x1b bytes mscorlib.dll!System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(...[생략]...) + 0x26a bytes mscorlib.dll!System.Runtime.Remoting.RemotingServices.ExecuteMessage(...[생략]...) + 0x63 bytes System.EnterpriseServices.dll!System.EnterpriseServices.ServicedComponentProxy.LocalInvoke(...[생략]...) + 0x1b3 bytes System.EnterpriseServices.dll!System.EnterpriseServices.ServicedComponentProxy.Invoke(...[생략]...) + 0x55 bytes System.EnterpriseServices.dll!System.EnterpriseServices.ServicedComponent.RemoteDispatchHelper(...[생략]...) + 0x38 bytes System.EnterpriseServices.dll!System.EnterpriseServices.ServicedComponent.System.EnterpriseServices.IRemoteDispatch.RemoteDispatchNotAutoDone(string s) + 0x14 bytes [Native to Managed Transition] </pre> <br /> 다음으로, C/C++ 클라이언트를 만들고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > #include "stdafx.h" #import "..\\..\\ConsoleApplication1\\ConsoleApplication1\\bin\\Debug\\TestCOMObj.tlb" no_namespace raw_interfaces_only int _tmain(int argc, _TCHAR* argv[]) { CoInitialize(NULL); { _MyClassPtr ptr; ptr.CreateInstance(__uuidof(MyClass)); VARIANT vtResult; ptr->DoIt(&vtResult); } CoUninitialize(); return 0; } </pre> <br /> 이제 호출을 해보면, C# COM+ 측의 콜스택이 어떻게 나올까요? 제 경우에는, 별반 다르지 않게 콜 스택이 나올 거라고 생각했는데, 그게 아니었습니다.<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='complus_from_nativecall_1.png' src='/SysWebRes/bbs/complus_from_nativecall_1.png' /><br /> <br /> 보시는 것처럼, System.EnterpriseServices, System.Runtime.Remoting.Messaging 클래스가 전혀 관여하지 않고 Native 클라이언트로부터 온 호출이 직접 전달되고 있습니다.<br /> <br /> 즉, .NET COM+ 개체 자체의 GC 등으로 인한 영향을 제외한다면 Native 클라이언트로부터 .NET COM+ 개체를 호출하는 경우 오버헤드가 전혀 없음을 알 수 있습니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1165
(왼쪽의 숫자를 입력해야 합니다.)