1.기존 C# DLL을 COM으로 노출 시켜야 함
-
(1)프로젝트->속성->Assembly 정보 -> 어셈블리를 COM에 노출 check
-
(2)프로젝트->속성->Build->COM Interop 등록 check
2.노출하고자 하는 Function을 포함하는 Interface를 구현
[ Guid ("8F42A31B-7C69-4E14-BF7A-56F243134852" )] public interface INDTComponent { int ShowTGCControl(byte[] tgcValue); }
3.해당 Interface를 상속하영 Class구현
[ Guid ("379AA4DF-991F-4A72-B091-9DCEE25D8DD5" )] public class NDTComponent : INDTComponent { public int ShowTGCControl( byte [] tgcValue) { frmImageAdjustmentCurve form = new frmImageAdjustmentCurve (); form . SetTGCValue(tgcValue); form . ShowDialog(); return 1 ; } }
4.C# DLL을 Build시 *.tlb 생성됨
5.C++ 프로젝트에서 연동하고자 하는 C# DLL의 tlb파일을 Import
#import "..\Bin\Release\NDTComponent.tlb" no_namespace named_guids
(참고)C++ 프로젝트 Compile후 tlh가 자동 생성됨
6. C# DLL을 호출
NDTComponentPtr ptr ( __uuidof( NDTComponent )); ptr->ShowTGCControl(); ptr->Release();
– Array 전달하기 : SAFEARRAY를 이용하여 전달
NDTComponentPtr ptr ( __uuidof( NDTComponent )); uchar tgcValue [ 256]; memset ( tgcValue, 0, sizeof( tgcValue )); SAFEARRAYBOUND sab ; sab . lLbound = 0; sab . cElements = 256; SAFEARRAY * pSA = SafeArrayCreate (VT_UI1 , 1 , &sab ); LONG index ; for (int i =0 ; i<256 ; i ++) { tgcValue [ i] = NDTData :: getInstance(). m_TGCValue [i ]; index = i; SafeArrayPutElement ( pSA, &index , &tgcValue [i ]); } ptr->ShowTGCControl(pSA); ptr->Release();
callback 함수 전달하기
1.C# DLL에 callback용 Delegate 선언
[UnmanagedFunctionPointer( CallingConvention.StdCall)] public delegate void CurveChangedCallback(byte [] curveValue);
2.C# DLL에 callback Parameter 추가
int ShowTGCControl([MarshalAs(UnmanagedType .FunctionPtr)]CurveChangedCallback callback);
3.C++에 callback용 함수 선언 및 구현
static NDTComponentCOM::CurveChanged(uchar* tgcValue);
4.C++에서 Parameter로 전달 (long)형으로 casting
void * curveCallback = NDTComponentCOM:: CurveChanged ; ptr->ShowTGCControl( nX , nY , pSA, (long ) curveCallback); ptr->Release();