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();