성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Reordering on an Alpha processor ;...
[정성태] 공유 감사합니다. ^^ 참고로, WPF에서 WindowsF...
[Tom Lee] 답변 감사합니다. 나름의 해결책 연구해보고 여기에도 공유해봅니다...
[정성태] 아래의 글을 보면, MoveWindow 하면 될 듯한데요. ^^...
[Tom Lee] 안녕하세요 올려주신 글 참고하여 WPF 어플리케이션 안에 Uni...
[정성태] A graphical depiction of the steps ...
[정성태] 질문을 주셔서 출판사 측에 문의를 했습니다. 약 한 달 정도 후...
[Thorondor
] @정성태 개인 블로그인데도 거의 커뮤니티 급 인 것 같아요. 요...
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>[in, out] 배열을 C#에서 C/C++로 넘기는 방법 - 두 번째 이야기</div><br /> <br /> 지난 글에 이어서.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > [in, out] 배열을 C#에서 C/C++로 넘기는 방법 ; <a target='_tab' href='/2/0/810'>http://www.sysnet.pe.kr/2/0/810</a> </pre> <br /> 마이크로소프트가 원래 의도한 바는 아니었겠지만, tlbimp.exe의 기능을 보정할 수 있는 방법을 별도로 제공하고 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > .NET Framework Developer's Guide - Customizing Runtime Callable Wrappers ; <a target='_tab' href='https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/e753eftz(v=vs.100)'>https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/e753eftz(v=vs.100)</a> </pre> <br /> 위의 글에 포함된 그림이 재미있습니다. ^^<br /> <br /> [그림 1: RCW DLL 생성 방법]<br /> <img alt='how_to_customize_rcw_1.gif' src='/SysWebRes/bbs/how_to_customize_rcw_1.gif' /><br /> <br /> RCW를 생성하는 3가지 방법 중에서 중간 그림이 의미가 있는데, 일단 한번 tlbimp.exe에 의해서 생성된 DLL을 역어셈블한 뒤, 원하는 대로 마샬링 정보를 바꾸고 다시 ilasm을 이용해서 DLL을 생성하고 있습니다. 오호... 이 정도면 훌륭한 대안이죠. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 이것을 이용해서 <a target='_tab' href='/2/0/810'>지난번 예제</a>를 개선해 보겠습니다.<br /> <br /> IDL은 원래 정의된 그대로 사용하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > [ object, uuid(1A38076B-3D6D-4F20-8B4D-C72EF6AE1204), dual, nonextensible, helpstring("IMyTest Interface"), pointer_default(unique) ] interface IMyTest : IDispatch { [id(0x3003), helpstring("method PrepareBuf")] HRESULT PrepareBuf(<b style='COLOR: blue'>[in, out, size_is(bufLength)] __int64 buffer []</b>, [in] int bufLength); }; </pre> <br /> 마샬링 정보가 올바르진 않겠지만 일단 tlbimp.exe(또는 Visual Studio의 DLL 참조)를 이용하여 interop DLL을 생성합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > tlbimp testatl.dll /out:interop.testatl.dll </pre> <br /> ildasm으로 DLL을 역어셈블하면 해당 메서드가 다음과 같이 선언된 것을 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > ildasm interop.testatl.dll /out:interop.testatl.il .method public hidebysig newslot virtual instance void PrepareBuf(<b style='COLOR: blue'>[in][out] int64& buffer</b>, [in] int32 bufLength) runtime managed internalcall { .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 03 30 00 00 00 00 ) // ...0.... .override interop.testatl.IMyTest::PrepareBuf } // end of method MyTestClass::PrepareBuf </pre> <br /> 여기에서 "[in][out] int64& buffer" 구문을 "[in][out] int64[] marshal([]) buffer"과 같이 바꿔줍니다. (또 한 군데 더 정의되어 있기 때문에 그 부분도 마저 바꿔줍니다.) 이렇게 변경하고 다시 ilasm으로 어셈블해주면, C#에서 정상적으로 long []으로 사용할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > ilasm interop.testatl.il /dll public virtual void PrepareBuf(<b style='COLOR: blue'>long[] buffer</b>, int bufLength); </pre> <br /> 우와~~~ ^^ 깔끔하죠! (<a target='_tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?wid=811&boardid=331301885'>첨부된 파일은 위의 예제와 지난번 글의 예제를 함께 테스트한 프로젝트</a>입니다.)<br /> <br /> 그러고 보니, 이걸 하면서 예전에 쓴 글이 하나 생각났습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > COM 개체의 이벤트를 구독하는 코드 제작 ; <a target='_tab' href='/2/0/589'>http://www.sysnet.pe.kr/2/0/589</a> </pre> <br /> 위의 방법 역시 interop DLL 코드가 잘못 생성된 경우인데, ildasm/ilasm 조합으로 해결할 수도 있었지 않았을까 싶네요. ^^<br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
5396
(왼쪽의 숫자를 입력해야 합니다.)