struct parameter를 C++ dll과 C# 간의 parameter 전달 방식을 정리 했습니다.

1.C++에서 Struct 선언

typedef struct tag ULTRASOUNDREGION {
             char RegionDataType[LEN_US + 1];
             float PhysicalDeltaX;
} ULTRASOUNDREGION

typedef struct tag DICOMINFO{
             char SOPClassUID[LEN_UI + 1];
             ULTRASOUNDREGION UltrasoundRegion[ 5 ];
} DICOMINFO

2.C#에서 Struct 선언

[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct ULTRASOUNDREGION
{  
        //배열을 전달시 UnmanagedType을 ByValArray로 설정 후 SizeConst에 배열의 크기(Index Count) 를 전달
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = VR.LEN_US + 1)]
        public char[] RegionDataType;

        [MarshalAs(UnmanagedType.R4)]
        public float PhysicalDeltaX;

        //선언 배열은 Struct 생성자(c# sturct는 최소1개의 Parameter 필요)에서 할당
        public ULTRASOUNDREGION(bool bInit) : this()
        {
            RegionSpatialFormat = new char[VR.LEN_US + 1];
        }
}

[Serializable]
[StructLayout( LayoutKind .Sequential, CharSet = CharSet.Ansi)]
public struct DICOMINFO
{  
        //구조체 배열도 동일하게 ByValArray로 설정, SizeConst는 구조체 배열의 Index Count로 설정
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5 ]
        public ULTRASOUNDREGION[] USRegion;

        //배열이 아닌 그냥 구조체로 전달시에는 UnmanagedType.Struct로 설정하여 전달, SizeConst는 Struct 실제 Size
        Ex)
        [MarshalAs(UnmanagedType.Struct, SizeConst = 40]
}

3.C++ DLL Function의 Parameter에 구조체 Pointer전달

Ex)
extern "C" DLLDECL int SaveDICOMFile( DICOMINFO *pDicomInfo , char *pBMPFilePath, char *pDICOMFilePath);

4.C# Module 선언부분에 구조체에 ref 추가

Ex)
[ DllImport("DCMTKInterface.dll", CallingConvention = CallingConvention .Cdecl)]
public static extern int SaveDICOMFile( ref DICOMINFO dicomInfo, char [] bmpFilePath, char [] dicomFilePath);

5.C#에서 C++로 return 받고자 하는 Struct Array를 전달시

C#)
void LoadNDTRawFile(NDTParam10[] pNDTParam);

c++)
void LoadNDTRawFile(NDTParam10* pNDTParam);

C++에서 data관련 처리후 pNDTParam[0] or pNDTParam[index]를 통해 값을 설정하면 C#측은 설정된 NDTParam10 array를 받을 수 있다.