2013-04-03 53 views
1

這裏是我的其他問題,導致這個一個作爲參考也: How to call managed C++ methods from Un-managed C++實現一個C#DLL COM文件在非託管C++程序

我已經成功地創建了一個C#COM文件。現在我需要一個關於如何在非託管C++中實現它的簡單解釋。

我跟着這個例子,但C++的部分是薄弱的。 http://www.codeproject.com/Articles/7859/Building-COM-Objects-in-C

這裏是我的COM文件

using System; 
using System.Runtime.InteropServices; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace cSharpRiJHarn 
{ 
    [Guid("ED1483A3-000A-41f5-B1BC-5235F5897872")] 
    public interface DBCOM_Interface 
    { 
     [DispId(1)] 
     String encrypt(string s); 
     [DispId(2)] 
     String decrpyt(string s); 
    } 

    [Guid("A6BCEC1D-B60C-4c97-B9AD-1FE72642A9F8"), 
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    public interface DBCOM_Events 
    { 
    } 

    [Guid("7C13A8C6-4230-445f-8C77-0CA5EDECDCB5"), 
    ClassInterface(ClassInterfaceType.None), 
    ComSourceInterfaces(typeof(DBCOM_Events))] 
    public class RijndaelLink : DBCOM_Interface 
    { 
     public String encrypt(String s) 
     { 
      return Rijndael.EncryptString(s); 
     } 
     public String decrpyt(String s) 
     { 
      return Rijndael.DecryptString(s); 
     } 
    } 
} 

我只是想使用此與非託管代碼一個非常簡單的例子。 請在您的答案:

  • 我需要包括項目或只是COM的源文件
  • 我需要添加引用
  • 一個路過的一個字符串的非常基本的例子,用cout打印出來。

感謝您的幫助!

+0

您需要的唯一東西就是編譯您提供的代碼,然後使用正確方法(引用COM庫)在非託管代碼內引用已編譯的COM庫以查找相關語言。由於你的問題含糊不清,我不會再具體了。 –

+0

我的錯誤是模糊。我會盡力而且更清楚。我想要一個從基本非託管C++控制檯程序調用上述加密和解密方法的示例。 –

回答

5

您需要做的第一件事是正確定義.NET中的COM對象,以供非託管世界(C++或其他)使用。這裏是一個不錯的定義:

namespace cSharpRiJHarn 
{ 
    [Guid("ED1483A3-000A-41f5-B1BC-5235F5897872")] 
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    [ComVisible(true)] 
    public interface IRijndaelLink 
    { 
     string encrypt(string s); 
     string decrypt(string s); 
    } 

    [Guid("7C13A8C6-4230-445f-8C77-0CA5EDECDCB5")] 
    [ComVisible(true)] 
    public class RijndaelLink : IRijndaelLink 
    { 
     public string encrypt(string s) 
     { 
      return Rijndael.EncryptString(s); 
     } 

     public string decrypt(string s) 
     { 
      return Rijndael.DecryptString(s); 
     } 
    } 
} 

接下來,你需要註冊.NET程序集使用RegAsm工具COM。我建議你也建立一個Type Library (.TLB)有了它,像這樣(我想你打造全工具和X86,X64沒有):

c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe YourAssembly.dll /tlb:YourAssembly.tlb /codebase 

請適應你的實際路徑。還請檢查代碼庫arg,因爲您可能不需要這些代碼。

這將生成一個.TLB文件,其中包含界面和類。它的工作原理是因爲我們添加了ComVisible屬性。您還會注意到我沒有定義Dispatch或Dual接口,因爲在本示例中,我不需要COM Automation(VB,VBA)或任何腳本語言(VBScript,JScript)支持,只有IUnknown接口更容易使用普通的C/C++比IDispatch接口。

現在,有一種簡單的方法可以使用Microsoft特定的C++擴展將其導入到非託管C++世界中:#import Directive,類似於.NET中的添加引用。下面是使用COM對象的樣本控制檯應用程序:

#include "stdafx.h" 
#import "c:\MyPathToTheTlb\YourAssembly.tlb" // import the COM TLB 

using namespace YourAssembly; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CoInitialize(NULL); // needed to enter COM space 
    IRijndaelLinkPtr ptr(__uuidof(RijndaelLink)); // create the COM Object with the desired interface 
    _bstr_t s = ptr->encrypt("hello"); // call the function 
    printf("%S", (LPWSTR)s); // for example 
    CoUninitialize(); 
    return 0; 
} 

你會發現#import指令也創造了涼爽的包裝(_bstr_t,如.NET字符串將在這裏導出爲自動化BSTR,甚至的IUnknown接口)對於字符串處理,所以它沒有什麼大不了的。

這不是所有這一切的唯一辦法,但這是恕我直言最簡單的一種。

+0

真棒解釋!神聖的廢話......這正是我所尋找的。明天我上班時我會試一試。謝謝! –

相關問題