在非托管 C++ 程序中实现 C# DLL COM 文件
Posted
技术标签:
【中文标题】在非托管 C++ 程序中实现 C# DLL COM 文件【英文标题】:Implement a C# DLL COM File In Unmanaged C++ Program 【发布时间】:2013-04-03 17:05:40 【问题描述】:这是我的另一个问题,也导致了这个问题作为参考: How to call managed C++ methods from Un-managed 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 打印出来的一个非常基本的示例。感谢您的帮助!
【问题讨论】:
您唯一需要做的就是编译您提供的代码,然后使用相关语言的正确方法(引用 COM 库)在非托管代码中引用已编译的 COM 库。由于您的问题含糊不清,我不会更具体。 我的错误是含糊不清。我会尝试更清楚。我想要一个从基本的非托管 c++ 控制台程序调用上述加密和解密方法的示例。 【参考方案1】:您需要做的第一件事是在 .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);
接下来,您需要使用RegAsm 工具为 COM 注册此 .NET 程序集。我还建议你用它构建一个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 接口也是如此)用于字符串处理,所以这没什么大不了的。
这不是所有这些工作的唯一方法,但恕我直言,这是最简单的方法之一。
【讨论】:
很棒的解释!废话……这正是我要找的。明天上班时我会试一试。谢谢!以上是关于在非托管 C++ 程序中实现 C# DLL COM 文件的主要内容,如果未能解决你的问题,请参考以下文章