在非托管C程序中实现C#DLL COM文件
作者:互联网
这是我提出的另一个参考问题:
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,因为在生产中可能不需要它.
这将建立一个同时包含接口和类的.TLB文件.之所以有效,是因为我们添加了ComVisible属性.您还将注意到,我没有定义Dispatch或Dual接口,因为在此示例中,我不需要COM Automation(VB,VBA)或任何脚本语言(VBScript,JScript)支持,仅需要IUnknown接口,这些接口在使用中更加容易使用普通的C/C++而不是IDispatch接口.
现在,有一种简单的方法可以使用Microsoft特定的C扩展名#import Directive将其导入非托管C世界中,类似于.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接口也是如此)以进行字符串处理,所以这没什么大不了的.
这不是所有这些都能起作用的唯一方法,但是恕我直言,恕我直言,这是最简单的方法之一.
标签:c,com,unmanaged,c-2 来源: https://codeday.me/bug/20191013/1906968.html