2010-07-06 4 views
3

가능하면 MSSCCI 공급자를 구현하고 싶습니다 .Net에서 구현하고 싶습니다. (따라서 내 MSSCCI 공급자는 실제로 .Net 구현 주위의 얇은 래퍼입니다).Net에서 MSSCCI 공급자 구현

  • 이것이 가능합니까?
  • 좋은 생각인가요?

.Net에서 구현한다는 것은 내 MSSCCI 공급자를 사용하는 모든 사람이 자신의 프로세스에서 .Net 프레임 워크를 호스팅해야한다는 것을 의미합니다. 이는 부당한 요청입니까? 또한 .Net에서 구현하기 위해 고려해야 할 다른 제한 사항은 무엇입니까?

답변

5

가능하고 비교적 쉽습니다. 나는 시간이 좀 전에 개발하고 잘 작동합니다. COM 상호 운용성을 C++에서 C#까지 사용했습니다.

그래서 두 dll을 만듭니다. C++ 하나는 API를 구현하는 래퍼 일 뿐이므로 C#에 COM을 호출합니다. C# 코드는 으로 등록해야합니다. com regasm/codebase가 포함 된 구성 요소 mycomlibrary.dll

구현 방법은 다음과 같습니다. 코드 샘플에서는 예제로 SccInitialize 함수 만 구현합니다. 희망이 도움이됩니다.

#include <comutil.h> 

/**********************************************************************************************************/ 
// Imports the COM object that implements the SCC API in .NET 
/**********************************************************************************************************/ 
#import "SccCOMServer.tlb" no_namespace named_guids 

static int s_nInitializedCount = 0; 

/**********************************************************************************************************/ 
// Starting point of the dll 
/**********************************************************************************************************/ 
BOOL APIENTRY DllMain( 
         HANDLE hModule, 
         DWORD ul_reason_for_call, 
         LPVOID lpReserved 
        ) 
{ 
    switch (ul_reason_for_call) 
    { 
     case DLL_PROCESS_ATTACH: 
     case DLL_THREAD_ATTACH: 
     case DLL_THREAD_DETACH: 
     case DLL_PROCESS_DETACH: 
     break; 
    } 
    return TRUE; 
} 

/**********************************************************************************************************/ 
// Variable with a instance of the COM object 
/**********************************************************************************************************/ 

ISccCOMServer *mCpi = NULL; 


/**********************************************************************************************************/ 
// Utility functions 
/**********************************************************************************************************/ 

void BSTR2T(BSTR s1, LPSTR s2) 
{ 
    _bstr_t s(s1, false); 
    strcpy(s2, s); 
} 

char* ConvertBSTRToLPSTR (BSTR bstrIn) 
{ 
    LPSTR pszOut = NULL; 
    if (bstrIn != NULL) 
    { 
     int nInputStrLen = SysStringLen (bstrIn); 

     // Double NULL Termination 
     int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, bstrIn, nInputStrLen, NULL, 0, 0, 0) + 2; 
     pszOut = new char [nOutputStrLen]; 

     if (pszOut) 
     { 
      memset (pszOut, 0x00, sizeof (char)*nOutputStrLen); 
      WideCharToMultiByte (CP_ACP, 0, bstrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0); 
     } 
    } 
    return pszOut; 
} 

/**********************************************************************************************************/ 
//          IMPLEMENTATION OF THE FUNCTIONS 
/**********************************************************************************************************/ 


/**********************************************************************************************************/ 
// Initialization and Housekeepeng Functions 
/**********************************************************************************************************/ 

SCCEXTERNC SCCRTN EXTFUN __cdecl SccInitialize(
    LPVOID * ppContext, 
    HWND hWnd, 
    LPCSTR lpCallerName, 
    LPSTR lpSccName, // [In, out] 
    LPLONG lpSccCaps, // [Out] 
    LPSTR lpAuxPathLabel, // [In, out] 
    LPLONG pnCheckoutCommentLen, // [Out] 
    LPLONG pnCommentLen //[Out] 
    ) 
{ 

    // Initialize COM the first time the function is called 
    CoInitialize(0); 
    s_nInitializedCount++; 
    HRESULT hr = CoCreateInstance(CLSID_ISccCOMServerImpl, 
     NULL, CLSCTX_INPROC_SERVER, 
     IID_ISccCOMServer, reinterpret_cast<void**>(&mCpi)); 

    long response; 

    // We need auxiliar strings because out string in COM are BSTR * 
    BSTR bstrSccName; 
    BSTR bstrAuxPathLabel; 

    bstrSccName = T2BSTR(lpSccName); 
    bstrAuxPathLabel = T2BSTR(lpAuxPathLabel); 

    Context *CC = new Context; 
    // Calling to the COM equivalent Function 

    response = mCpi->Initialize(CC, (long) hWnd, lpCallerName, &bstrSccName, lpSccCaps, &bstrAuxPathLabel, 
     pnCheckoutCommentLen, pnCommentLen); 

    *ppContext = (void *)CC; 

    // Converting the strings 
    BSTR2T(bstrSccName, lpSccName); 
    BSTR2T(bstrAuxPathLabel, lpAuxPathLabel); 
    return response; 

} 

그리고 다음 C# 부분은 간단하다 :

[Guid("C6659361-1625-4746-931C-36014B146679")] 
public class ISccCOMServerImpl : ISccCOMServer 
{ 
    public int Initialize(
     out Context ppContext, 
     IntPtr hWnd, 
     string lpCallerName, 
     ref string lpSccName, // out 
     out int lpSccCaps, // out 
     ref string lpAuxPathLabel, // out 
     out int pnCheckoutCommentLen, // out 
     out int pnCommentLen //out 
     ) 
    { 
     //your manage code here! 
    } 

}

C++ 구성 요소입니다