繁体   English   中英

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

[英]Implement a C# DLL COM File In Unmanaged C++ Program

这是我引起这个问题的另一个问题,也作为参考: 如何从非托管C ++调用托管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程序集。 我建议您还使用它构建类型库(.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字符串将在此处导出为Automation BSTR,甚至对于IUnknown接口也是如此)以进行字符串处理,所以这没什么大不了的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM