在.Net中实现MSSCCI提供程序

问题描述:

我想实现一个MSSCCI提供程序,但是如果可能的话我想在.Net中实现它(所以我的MSSCCI提供程序实际上是一个围绕.Net实现的薄包装)在.Net中实现MSSCCI提供程序

  • 这可能吗?
  • 这是个好主意吗?

我知道,在使用.NET实施那岂不是用我的MSSCCI提供人将*主持他们的过程中.net框架 - 这是一个不合理的要求?如果我要在.Net中实现,还需要考虑其他什么限制?

这是可能的,并且相对容易。我前一段时间开发了一款,效果很好。我使用了从C++C#的COM互操作性。

因此,您将创建两个dll。 C++一个只是一个实现API的包装,将调用传递给COM,其中C#。 C#必须注册为COM带regasm/codebase的组件mycomlibrary.dll

以下是一些实现它的指导原则。在代码示例中,我仅以SccInitialize函数为例。希望能帮助到你。

这是C++组分:

#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! 
    } 

}