什么是Assembly(程序集)?

本文介绍了.NET框架中的Assembly(程序集)概念,包括其定义、作用及如何使用Assembly类获取程序的类和实例信息。通过一个具体示例展示了如何动态加载程序集并创建对象,从而实现更灵活的设计模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://hi.baidu.com/leyhui/blog/item/58de0559cbeead292934f0d8.html

什么是Assembly(程序集)? Assembly是一个包含来程序的名称,版本号,自我描述,文件关联关系和文件位置等信息的一个集合。在.net框架中通过Assembly类来支持,该类位于System.Reflection下,物理位置位于:mscorlib.dll。 Assembly能干什么? 我们可以通过Assembly的信息来获取程序的类,实例等编程需要用到的信息。 一个简单的演示实例: 1.建立一个Console工程名为:NamespaceRef 2.写入如下代码:

1using System; 2using System.Collections.Generic; 3using System.Text; 4using System.Reflection; 5 6namespace NamespaceRef 7{ 8    class Program 9    { 10        static void Main(string[] args) 11        { 12             Person cy; 13             String assemblyName = @"NamespaceRef"; 14            string strongClassName = @"NamespaceRef.Chinese"; 15            // 注意:这里类名必须为强类名 16            // assemblyName可以通过工程的AssemblyInfo.cs中找到 17             cy = (Country)Assembly.Load(assemblyName).CreateInstance(strongClassName); 18             Console.WriteLine(cy.name); 19             Console.ReadKey(); 20         } 21     } 22 23    class Person 24    { 25        public string name; 26     } 27 28    class Chinese : Person 29    { 30        public Chinese() 31        { 32             name = "你好"; 33         } 34     } 35 36    class American : Person 37    { 38        public American() 39        { 40             name = "Hello"; 41         } 42     } 43}
由于Assembly的存在给我们在实现设计模式上有了一个更好的选择。 我们在开发的时候有时候会遇到这样的一个问题,根据对应的名称来创建指定的对象。如:给出chinese就要创建一个chinese对象,以前我们只能这样来写代码:
1if (strongClassName == "China") 2     cy = new China(); 3else if (strongClassName == "America") 4     cy = new America();
那么如果我们有很长的一系列对象要创建,这样的代码维护起来是很困难的,而且也不容易阅读。现在我们可以通过在外部文件定义类的程序集名称和类的强名称来获得这样一个实例,即易于理解,又增强了扩展性还不用修改代码。 cy = (Country)Assembly.Load(assemblyName).CreateInstance(strongClassName); 结论 Assembly类有很多的方法和属性,它和Type一样有很多功能用于名称与方法和属性之间的转化。深入理解这两个类,你就可以清晰通用语言层是如何工作。 in the c# language there are these several conceps:program,types,members,namespace, and assembly. the difference between them is: program is consist of source files. source files could contain types(such as classes and interfaces) which may have some members(such as property, methods, fields, and events). types can be orgnized under the namespaces. when the program is compiled it is in an assembly(such as .exe or .dll).
<think>我们需要在C++中调用.NET程序集Assembly)。这通常可以通过两种主要方式实现: 1. 使用COM Interop:将.NET程序集暴露为COM组件,然后在C++中像调用COM一样调用。 2. 使用CLR Hosting:在C++程序中宿主(Host)CLR(公共语言运行时),然后通过CLR加载和运行.NET程序集。 这里我们重点介绍第二种方法,因为它是更直接且现代的方法,不需要注册COM。 步骤: 1. 初始化CLR环境。 2. 获取默认AppDomain。 3. 加载.NET程序集。 4. 获取类型并调用方法。 以下是一个详细的示例代码,使用C++(使用Visual C++编译器)调用一个.NET程序集中的方法。 假设我们有一个.NET类库(DLL)名为MyDotNetLib.dll,其中包含一个类`MyClass`,该类有一个静态方法`Add`,接受两个整数并返回它们的和。 首先,我们需要确保项目设置支持CLR。在Visual Studio中,我们可以创建一个C++项目,并设置“公共语言运行时支持”(/clr)或者使用纯本地C++代码通过Hosting CLR来调用。这里我们使用纯本地C++通过Hosting接口。 注意:以下代码需要链接mscoree.lib,并且需要安装.NET框架。 代码示例:</think>在C++中调用.NET程序集可以通过两种主要方式实现:**COM Interop**或**CLR Hosting**。以下是详细解决方案: ### 方法1:CLR Hosting(推荐) 通过C++代码直接加载CLR运行时,执行.NET程序集: ```cpp #include <metahost.h> #pragma comment(lib, "mscoree.lib") void CallDotNetAssembly() { ICLRMetaHost* pMetaHost = nullptr; ICLRRuntimeInfo* pRuntimeInfo = nullptr; ICLRRuntimeHost* pClrRuntimeHost = nullptr; // 初始化CLR MetaHost CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost); // 获取运行时信息(使用v4.0.30319) pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimeInfo); // 判断是否可运行 BOOL fLoadable; pRuntimeInfo->IsLoadable(&fLoadable); if (fLoadable) { // 加载CLR运行时 pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pClrRuntimeHost); pClrRuntimeHost->Start(); // 执行.NET程序集 DWORD retVal = 0; HRESULT hr = pClrRuntimeHost->ExecuteInDefaultAppDomain( L"C:\\Path\\To\\YourAssembly.dll", // 程序集路径 L"YourNamespace.YourClass", // 完整类名 L"YourMethod", // 静态方法名 L"optional_parameters", // 参数 &retVal // 返回值 ); if (SUCCEEDED(hr)) { printf("Method returned: %d\n", retVal); } pClrRuntimeHost->Stop(); } // 清理资源 if (pClrRuntimeHost) pClrRuntimeHost->Release(); if (pRuntimeInfo) pRuntimeInfo->Release(); if (pMetaHost) pMetaHost->Release(); } ``` ### 关键代码解释: 1. **CLR初始化** `CLRCreateInstance` 初始化MetaHost接口,用于获取运行时信息。 2. **运行时选择** `GetRuntime` 指定.NET版本(推荐v4.0.30319),通过`IsLoadable`验证兼容性。 3. **执行程序集** `ExecuteInDefaultAppDomain` 执行静态方法,需提供: - 程序集物理路径 - 完整类名(含命名空间) - 静态方法名 - 参数(字符串格式) - 返回值的指针 4. **资源释放** 使用`Release()`释放COM接口,避免内存泄漏。 --- ### 方法2:COM Interop 适用于将.NET类暴露为COM组件: 1. **在.NET项目中启用COM可见性** 修改AssemblyInfo.cs: ```csharp [assembly: ComVisible(true)] [assembly: Guid("YOUR-GUID-HERE")] ``` 2. **定义接口和类** ```csharp [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IYourInterface { int Add(int a, int b); } [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] public class YourClass : IYourInterface { public int Add(int a, int b) => a + b; } ``` 3. **注册COM组件** 管理员身份运行: ```bash regasm YourAssembly.dll /tlb /codebase ``` 4. **C++调用代码** ```cpp #import "YourAssembly.tlb" named_guids raw_interfaces_only void CallViaCOM() { CoInitialize(NULL); IYourInterfacePtr pDotNet(__uuidof(YourClass)); long result = 0; pDotNet->Add(2, 3, &result); printf("Result: %d\n", result); CoUninitialize(); } ``` --- ### 两种方法对比 | **特性** | CLR Hosting | COM Interop | |-------------------|---------------------------------|---------------------------| | 部署复杂度 | 无需注册 | 需regasm注册 | | 版本控制 | 可指定.NET运行时版本 | 依赖注册表 | | 性能 | 直接高效 | COM调用有额外开销 | | 参数传递 | 支持复杂类型 | 需兼容COM数据类型 | | 适用场景 | 深度集成/控制CLR | 遗留系统/跨语言兼容 | --- ### 常见问题解决 1. **CLR初始化失败** 检查目标机器安装的.NET版本,使用`pRuntimeInfo->GetVersionString`验证运行时版本。 2. **方法执行失败** 确保: - 方法为`public static` - 参数数量/类型匹配 - 程序集依赖项已部署 3. **64/32位问题** C++项目平台需与.NET程序集架构一致(x86/x64)。 4. **路径问题** 使用绝对路径或将程序集放在可定位目录。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值