2013-04-03 55 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

真棒解释!神圣的废话......这正是我所寻找的。明天我上班时我会试一试。谢谢! –

相关问题