728x90
[in,out] 배열을 C# 에서 C/C++ 로 넘기는 방법
가령, long 형 배열을 C/C++에 넘겨주고, C/C++ 측에서 해당 배열의 내용을 채운 후 반환해 주는 메서드라면 다음과 같이 IDL 정의를 해줄 수 있습니다.
[ object, uuid(1A38076B-3D6D-4F20-8B4D-C72EF6AE1204), dual, nonextensible, helpstring("IMyTest Interface"), pointer_default(unique) ] interface IMyTest : IDispatch { [id(0x3003), helpstring("method PrepareBuf1")] HRESULT PrepareBuf([in, out, size_is(bufLength)] __int64 buffer [], [in] int bufLength); };
그런데, tlbimp.exe (또는 Visual Studio의 DLL 참조)를 이용하여 interop DLL을 생성해 보면, PrepareBuf 의 함수 형식이 다음과 같이 정의되는 것을 볼 수 있습니다.
tlbimp testatl.dll /out:interop.testatl.dll public virtual void PrepareBuf(ref long buffer, int bufLength);
오호... tlbimp.exe로써는, 감당이 안되는 IDL 구문이라는 것인데요. 그렇다면 이를 해결하기 위해서 생각해 볼 수 있는 것이 배열 자체를 포인터로 넘겨보는 정도일텐데, 약간 찜찜하긴 해도 4byte(혹은 8byte) 값으로 넘기는 것은 ^^ 너무 잘 동작합니다.
그래서 C# 측에서, 배열 자체를 IntPtr로 변경하고,
[STAThread] static void Main(string[] args) { interop.testatl.MyTestClass mtc = new interop.testatl.MyTestClass(); long [] test = new long[5]; IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(test, 0); mtc.PrepareBuf(ptr.ToInt64(), 5); for (int i = 0; i < 5; i++) { Console.WriteLine(test[i]); } }
C/C++ 에서는 넘겨받은 정수값을 간단하게 포인터로 형변환해서 처리해 주면 됩니다.
STDMETHOD(PrepareBuf2)(__int64 buffer, int bufLength) { __int64 *pBuffer = (__int64 *)buffer; for (int i = 0; i < bufLength; i ++ ) { pBuffer[i] = i; } return S_OK; }
물론, 이 방법은 out-of-process COM 개체로 만들면 프로세스 주소 공간이 달라지기 때문에 동작하지 않습니다. 하지만, In-proc COM 개체만으로 사용하실 분들이라면 이 방법이 나쁘다고 볼 수는 없습니다.
출처 : http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&pageno=0&detail=1&wid=810
728x90
'Basic Programming > CLI' 카테고리의 다른 글
CLI - 배열을 C#에서 C/C++로 넘기는 방법 (2/2) (0) | 2018.10.10 |
---|---|
CLI - 제공되는 명시적인 파괴자의 비밀 (0) | 2018.10.08 |
CLI - Native C++ 개발자를 위한 C++/CLI (0) | 2018.10.02 |