c# - 在非托管 C++ 程序中实现 C# DLL COM 文件

标签 c# c++ com unmanaged

这是我提出的另一个问题,也可以作为引用: 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 打印出来的非常基本的示例。

感谢您的帮助!

最佳答案

您需要做的第一件事是在 .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,因为您在生产中可能不需要它。

这将构建一个包含接口(interface)和类的 .TLB 文件。它起作用是因为我们添加了 ComVisible属性。您还会注意到我没有定义 Dispatch 或 Dual 接口(interface),因为在此示例中,我不需要 COM Automation (VB、VBA)或任何脚本语言(VBScript、JScript)支持,只有 IUnknown 接口(interface),在纯 C/C++ 中比 IDispatch 接口(interface)更容易使用。

现在,有一种简单的方法可以使用 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 String 在这里将作为 Automation BSTR 导出,即使对于 IUnknown 接口(interface)也是如此),所以这没什么大不了的。

这不是所有这些工作的唯一方法,但恕我直言,这是最简单的方法之一。

关于c# - 在非托管 C++ 程序中实现 C# DLL COM 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15793668/

相关文章:

c# - 如何使用 Entity Framework 代码优先从数据库中删除所有相关实体

c# - 如何在 ElasticSearch 查询中使用 ABS 函数?

C++:使用用户定义的泛型函数

c++ - 当我的程序终止时,我应该总是在 COM 指针上调用 Release 吗?

c# - 字符串替换的正则表达式模式

c# - ASP.NET Core 5 错误 “An error occurred while processing your request”

c++ - 如何从头文件中初始化私有(private)数组C++

c++ - OpenCV C++ 接口(interface)上的 CamShift 问题

c# - 编码 IDispatch 时出现 COM Interop 灾难性故障 (0x8000FFFF)

与 IXMLDOMNode* 相关的 C++ 错误