C++ 구조체 포인터의 값을 C# 구조체 배열로 가져오기
프로그래밍 2011. 3. 14. 14:33 |- C++ Struct 1
typedef struct _DATASTRUCT { wchar_t name[20]; wchar_t path[255]; int level; } DATASTRUCT, *LPDATASTRUCT; |
- C# Struct 1
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct DATASTRUCT { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string name; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)] public string path; public int level; } |
C++ 과 C# 의 구조체는 앞과 같다.
- C# 예제 코드
int MAX_COUNT = 10; DATASTRUCT[] dataStructs; [DllImport(@".\SendDataObject.dll", CharSet = CharSet.Unicode)] private static extern int GetDatas(DATASTRUCT[] dataStruct, intbufSizeCount, ref IntPtr returnPtr); . . IntPtr returnPtr = IntPtr.Zero; dataStructs = new DATASTRUCT[MAX_COUNT]; // 구조체 배열 초기화 또는 기타 처리 할 것 GetDatas(dataStructs, MAX_COUNT, ref returnPtr); int next = 0; for (int index = 0; index < MAX_COUNT; index++) { DATASTRUCT resultData = (DATASTRUCT)Marshal.PtrToStructure(newIntPtr(returnPtr.ToInt32() + next), dataStruct.GetType()); next += Marshal.SizeOf(dataStruct.GetType()); } . . |
- C++ 예제 코드
SEND_DATASTRUCTURE_API int GetDatas(LPDATASTRUCT lpDataStruct, int bufSizeCount,HRESULT& dataStructPtr) { try { dataStructPtr = (HRESULT)lpDataStruct; . . . } catch (...) { SCDI_TRACE(L"[SEND_DATASTRUCTURE_API] GetDatas() Error"); return -1; } return 0; } |
C++ 에서 LPDATASTRUCT 구조체에 다수의 구조체 정보를 저장해 놓을 수 있다. 그렇다면 C# 에서는 그 값을 꺼내서 사용 해야 하는데. C# 에서 “ref” 를 이용하면 되지 않겠는가? 라고 생각 하실 겁니다. 해보았으나 결과는Collection 이 1 개만 넘어와서 그 이상의 값을 꺼내 올 수 가 없었다.
DATASTRUCT resultData = (DATASTRUCT)Marshal.PtrToStructure(newIntPtr(returnPtr.ToInt32() + next), dataStruct.GetType()); next += Marshal.SizeOf(dataStruct.GetType()); |
C# 에서는 바로 앞의 코드가 핵심이다. Marshal.PtrToStructure 를 이용해서 해당 주소값의 위치에서 구조체를 꺼내 온다.
본 예제 에서는 10 개의 배열 구조체를 만들어 사용했다.
Marshal.SizeOf(dataStruct.GetType()) 는 구조체의 SizeOf 로 해당 Size 만큼 주소 값을 이동 시키면서 구조체를 꺼내 오면 된다.
앞에서와 같은 방법도 방법이였지만 그래서 DLL Import 부분을 다음과 같이 수정해 보았다. [Out] 을 사용한 것이다.
[DllImport(@".\SendDataObject.dll", CharSet = CharSet.Unicode)] private static extern int GetDatas([Out] DATASTRUCT[] dataStruct, intbufSizeCount, ref IntPtr returnPtr); |
그리 하였더니 깔끔하게 값들을 잘 가져왔다.
GetDatas([Out] DATASTRUCT[] dataStruct, int bufSizeCount, ref IntPtr returnPtr); |
즉, 앞에서 포인터 값을 이용하는 방식을 사용할 필요가 없었다. 하지만 앞에서와 같은 방식도 어디선가 쓰일 일이 때론 있을 것이다.
[출처] C++ 구조체 포인터의 값을 C# 구조체 배열로 가져오기|작성자 jackylim
'프로그래밍' 카테고리의 다른 글
안드로이드 시스템 rw로 마운트하기 (0) | 2011.05.03 |
---|---|
Linux or UINX dlopen 사용예제 (0) | 2011.03.15 |
vc++ 호출 규약 (0) | 2011.03.14 |
C# C에서 쓰던 typedef 및 #define 사용하기 (0) | 2011.03.14 |
/MD, /MT의 컴파일 옵션의 차이점 (0) | 2011.02.15 |