c#中using System.Runtime.InteropServices命名空间底下有几个重要的类,比如dllimport等。一系列的类来对COM对象进行操作。交互性操作用的,比如你可以将com组件适配成com+组件,
Classes
AllowReversePInvokeCallsAttribute |
Allows an unmanaged method to call a managed method. |
AutomationProxyAttribute |
Specifies whether the type should be marshaled using the Automation marshaler or a custom proxy and stub. |
BestFitMappingAttribute |
Controls whether Unicode characters are converted to the closest matching ANSI characters. |
BStrWrapper |
Marshals data of type |
ClassInterfaceAttribute |
Indicates the type of class interface to be generated for a class exposed to COM, if an interface is generated at all. |
CoClassAttribute |
Specifies the class identifier of a coclass imported from a type library. |
ComAliasNameAttribute |
Indicates the COM alias for a parameter or field type. |
ComAwareEventInfo |
Permits late-bound registration of an event handler. |
ComCompatibleVersionAttribute |
Indicates to a COM client that all classes in the current version of an assembly are compatible with classes in an earlier version of the assembly. |
ComConversionLossAttribute |
Indicates that information was lost about a class or interface when it was imported from a type library to an assembly. |
ComDefaultInterfaceAttribute |
Specifies a default interface to expose to COM. This class cannot be inherited. |
ComEventInterfaceAttribute |
Identifies the source interface and the class that implements the methods of the event interface that is generated when a coclass is imported from a COM type library. |
ComEventsHelper |
Provides methods that enable .NET Framework delegates that handle events to be added and removed from COM objects. |
COMException |
The exception that is thrown when an unrecognized HRESULT is returned from a COM method call. |
ComImportAttribute |
Indicates that the attributed type was previously defined in COM. |
ComRegisterFunctionAttribute |
Specifies the method to call when you register an assembly for use from COM; this enables the execution of user-written code during the registration process. |
ComSourceInterfacesAttribute |
Identifies a list of interfaces that are exposed as COM event sources for the attributed class. |
ComUnregisterFunctionAttribute |
Specifies the method to call when you unregister an assembly for use from COM; this allows for the execution of user-written code during the unregistration process. |
ComVisibleAttribute |
Controls accessibility of an individual managed type or member, or of all types within an assembly, to COM. |
CriticalHandle |
Represents a wrapper class for handle resources. |
CurrencyWrapper |
Wraps objects the marshaler should marshal as a |
DefaultCharSetAttribute |
Specifies the value of the CharSet enumeration. This class cannot be inherited. |
DefaultDllImportSearchPathsAttribute |
Specifies the paths that are used to search for DLLs that provide functions for platform invokes. |
DefaultParameterValueAttribute |
Sets the default value of a parameter when called from a language that supports default parameters. This class cannot be inherited. |
DispatchWrapper |
Wraps objects the marshaler should marshal as a |
DispIdAttribute |
Specifies the COM dispatch identifier (DISPID) of a method, field, or property. |
DllImportAttribute |
Indicates that the attributed method is exposed by an unmanaged dynamic-link library (DLL) as a static entry point. |
ErrorWrapper |
Wraps objects the marshaler should marshal as a |
ExternalException |
The base exception type for all COM interop exceptions and structured exception handling (SEH) exceptions. |
FieldOffsetAttribute |
Indicates the physical position of fields within the unmanaged representation of a class or structure. |
GuidAttribute |
Supplies an explicit Guid when an automatic GUID is undesirable. |
HandleCollector |
Tracks outstanding handles and forces a garbage collection when the specified threshold is reached. |
ImportedFromTypeLibAttribute |
Indicates that the types defined within an assembly were originally defined in a type library. |
InAttribute |
Indicates that data should be marshaled from the caller to the callee, but not back to the caller. |
InterfaceTypeAttribute |
Indicates whether a managed interface is dual, dispatch-only, or |
InvalidComObjectException |
The exception thrown when an invalid COM object is used. |
InvalidOleVariantTypeException |
The exception thrown by the marshaler when it encounters an argument of a variant type that can not be marshaled to managed code. |
LCIDConversionAttribute |
Indicates that a method's unmanaged signature expects a locale identifier (LCID) parameter. |
ManagedToNativeComInteropStubAttribute |
Provides support for user customization of interop stubs in managed-to-COM interop scenarios. |
Marshal |
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks, and converting managed to unmanaged types, as well as other miscellaneous methods used when interacting with unmanaged code. |
MarshalAsAttribute |
Indicates how to marshal the data between managed and unmanaged code. |
MarshalDirectiveException |
The exception that is thrown by the marshaler when it encounters a MarshalAsAttribute it does not support. |
MemoryMarshal |
Provides methods to interoperate with Memory<T>, ReadOnlyMemory<T>, Span<T>, andReadOnlySpan<T>. |
NativeLibrary |
Provides APIs for managing native libraries. |
OptionalAttribute |
Indicates that a parameter is optional. |
OutAttribute |
Indicates that data should be marshaled from callee back to caller. |
PreserveSigAttribute |
Indicates that the HRESULT or |
PrimaryInteropAssemblyAttribute |
Indicates that the attributed assembly is a primary interop assembly. |
ProgIdAttribute |
Allows the user to specify the ProgID of a class. |
RuntimeEnvironment |
Provides a collection of |
RuntimeInformation |
Provides information about the .NET runtime installation. |
SafeArrayRankMismatchException |
The exception thrown when the rank of an incoming |
SafeArrayTypeMismatchException |
The exception thrown when the type of the incoming |
SafeBuffer |
Provides a controlled memory buffer that can be used for reading and writing. Attempts to access memory outside the controlled buffer (underruns and overruns) raise exceptions. |
SafeHandle |
Represents a wrapper class for operating system handles. This class must be inherited. |
SEHException |
Represents structured exception handling (SEH) errors. |
SequenceMarshal |
Provides a collection of methods for interoperating with ReadOnlySequence<T>. |
StandardOleMarshalObject |
Replaces the standard common language runtime (CLR) free-threaded marshaler with the standard OLE STA marshaler. |
StructLayoutAttribute |
Lets you control the physical layout of the data fields of a class or structure in memory. |
TypeIdentifierAttribute |
Provides support for type equivalence. |
TypeLibFuncAttribute |
Contains the FUNCFLAGS that were originally imported for this method from the COM type library. |
TypeLibImportClassAttribute |
Specifies which Type exclusively uses an interface. This class cannot be inherited. |
TypeLibTypeAttribute |
Contains the TYPEFLAGS that were originally imported for this type from the COM type library. |
TypeLibVarAttribute |
Contains the VARFLAGS that were originally imported for this field from the COM type library. |
TypeLibVersionAttribute |
Specifies the version number of an exported type library. |
UnknownWrapper |
Wraps objects the marshaler should marshal as a |
UnmanagedFunctionPointerAttribute |
Controls the marshaling behavior of a delegate signature passed as an unmanaged function pointer to or from unmanaged code. This class cannot be inherited. |
VariantWrapper |
Marshals data of type |
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices?view=netcore-3.1
用System.Runtime.InteropServices服务的DllImport方法引入非托管代码程序集:https://blog.csdn.net/feiyingzaishi/article/details/72870247
什么叫非托管代码呢?非托管代码是在公共语言运行库(CLR)环境的外部,由操作系统直接执行的代码。非托管代码 (unmanaged code),因为是在CLR外部运行的,所以必须提供自己的垃圾回收、类型检查、安全支持等服务,它与托管代码不同,后者从公共语言运行库(CLR,类似JVM)中获得这些服务,而非托管代码是在运行库之外运行的代码。例如C++ COM 组件、ActiveX 接口和 Win32 API 函数都是非托管代码的示例。
托管/非托管是微软的.net framework中特有的概念:https://blog.csdn.net/z2516305651/article/details/93421861
Interoping .NET and C++ through COM(通过COM实现.NET和C++的互操作性)
Create COM visible types in C# and consume them from C++。
It is not uncommon that we have to put to work together native and .NET managed components. When you have to consume a managed component in native code, there are basically two options: through a mixed-mode component written in C++/CLI or through COM. This article will discuss the later and walk you through some of the key parts to help you understand the mechanism and get going with it. In this article, you will learn to:
我们需要把.NET组件与native代码放在一起工作,这并不少见。当你需要在native本机代码中使用managed托管组件时,有两个选择:通过C++/CLI或通过COM编写的混合模式组件。本文将讨论后者内容(通过COM编写的混合模式组件),并指导您完成一些关键部分,以帮助您理解该机制并开始使用它。本文中,你将学到:
- write COM visible interface and classes in C# and expose them through COM在C#中编写COM接口,通过COM接口调用
- import a type library in C++导入C++类型库
- use COM smart pointers to consume the COM components通过COM智能指针来使用COM组件
- understand the various type library files created in the process了解过程中创建的各种类型库文件
- understand the marshalling of types between C# and C++理解C#与C++之间的交互类型
- handle marshaled arrays处理交互的数组
- handle marshaled interfaces处理交互的接口
Creating a .NET in-proc COM Server(创建一个.NET进程中的COM服务器)
The first thing to start with is creating a .NET class library project that will represent an in-proc COM server. To this library, we will add, for the start, an interface called ITest
and a class that implements it called Test
. To a bare minimum, these will look as below:
第一件事就是创建一个.NET类库项目,它表示一个进程中的COM服务器。在这个库中,我们将添加,一个接口ITest和一个类Test。最少情况下,它们看起来如下:
namespace ManagedLib { [Guid("D3CE54A2-9C8D-4EA0-AB31-2A97970F469A")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] [ComVisible(true)] public interface ITest { [DispId(1)] void TestBool(bool b); [DispId(4)] void TestSignedInteger(sbyte b, short s, int i, long l); } [Guid("A7A5C4C9-F4DA-4CD3-8D01-F7F42512ED04")] [ClassInterface(ClassInterfaceType.None)] [ComVisible(true)] [ProgId("ManagedLib.Test")] public class Test : ITest { public void TestBool(bool b) { Console.WriteLine($"bool: {b}"); } public void TestSignedInteger(sbyte b, short s, int i, long l) { Console.WriteLine($"sbyte: {b}"); Console.WriteLine($"short: {s}"); Console.WriteLine($"int: {i}"); Console.WriteLine($"long: {l}"); } } }
定义接口和实现类没有什么特别之处,除了接口/类上使用的几个属性和控制这些实体如何暴露到COM的方法。
GuidAttribute | Specifies the GUID that defines the interface or class unique identifier. |
ComVisibleAttribute | Controls the accessibility of a type or member to COM. By setting the visibility parameter to true , we indicate that the type or member is visible to COM. |
InterfaceTypeAttribute | Specifies the type of COM interface a managed interface is when exposed to COM. The options specified in this sample is InterfaceIsIDispatch , which means the interface is dispinterface . This enables late binding only, with the methods and properties of the interface not part of the VTBL of the interface, and accessible through IDispatch::Invoke() only. |
ClassInterfaceAttribute | Specifies what kind of interface should be generated for the COM class. The options None specified above indicates that the class provides late-bind access through the IDispatch interface and no class interface is generated for the class. |
DispIdAttribute | Specifies the COM dispatch ID for a method, property or field. |
ProgIdAttribute | Allows to specify a programmable ID, which is a human friendly name for the COM class and must be unique within the system (just like the class ID). |
The next thing to do is registering the class library for COM interop from Project properties > Build. This can be done manually with regasm.exe, but by checking this option in the project settings, Visual Studio will run this tool with the /tlb and /codebase options. regasm.exe does all the registration necessary for the COM library to work. With the /tlb option, it also generates a Type Library file (.tlb) that contains definitions of the assembly types that are COM visible. With the /codebase option, it performs the registration from your project directory and not from GAC.
接下来要做的是从projectproperties>Build为COM互操作注册类库。这可以用手动完成regasm.exe,但通过在项目设置中选中此选项,VisualStudio将使用/tlb和/codebase选项运行此工具。regasm.exe执行COM库工作所需的所有注册。使用/tlb选项,它还生成一个类型库文件(.tlb),该文件包含COM可见的程序集类型的定义。使用/codebase选项,它从项目目录而不是从GAC执行注册。
Importing a Type Library in C++(在C++中导入类型库)
A type library is a binary file that contains information about COM interfaces, methods, and properties. This information is accessible to other applications at runtime. In VC++, it is possible to generate C++ classes based on this information and therefore provide early binding to the COM components. This is possible by using the #import
directive.
类型库是一个二进制文件,包含有关COM接口、方法和属性的信息。其他应用程序在运行时可以访问此信息。在VC++中,可以根据这些信息生成C++类,从而提供对COM组件的早期绑定。这可以通过使用#import指令来实现。
#import "ManagedLib.tlb"
The general form is #import filename [attributes]
, where the filename can be a type library (.tlb, .olb, .dll), an executable, a library containing a type library resource (.ocx), the programmatic ID of a control in a type library, the library ID of a type library, or any other format that can be understood by LoadTypeLib. The attributes are optional and control the content of the resulting headers. For details about the way the import directive works, check its MSDN documentation.
一般形式是#import filename[attributes],其中文件名可以是类型库(.tlb、.olb、.dll)、可执行文件、包含类型库资源的库(.ocx)、类型库中控件的编程ID、类型库的库ID或LoadTypeLib可以理解的任何其他格式。这些属性是可选的,并控制结果标头的内容。有关import指令工作方式的详细信息,请查看其MSDN文档。
The result of importing a type library are two header files, with the same name as the type library file, but different extensions:
导入类型库的结果是两个头文件,它们的名称与类型库文件相同,但扩展名不同:
https://www.codeproject.com/Articles/1195963/Interoping-NET-and-Cplusplus-through-COM
C++/CLI:https://www.cnblogs.com/bile/p/8081497.html
用C++/CLI搭建C++和C#之间的桥梁:https://www.cnblogs.com/Roarsun/p/11019727.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2019-11-02 定量遥感会议
2019-11-02 gdal栅格矢量化