托管 CLR:当某些参数是枚举时,从 C++ 反射调用 .NET 构造函数/方法

问题描述 投票:0回答:1

我有一个托管 CLR 的本机程序(即手动启动它,获取对

AppDomain
的引用等 - 这不是 C++/CLI)。在这种情况下,我想实例化一个 FileStream
 对象。

据我了解,在这种情况下创建对象的最佳方法是使用反射:

SAFEARRAY* pArgs = SafeArrayCreateVector(VT_VARIANT, 0, 2); ... BSTR assemblyName = SysAllocString(L"mscorlib"); BSTR typeName = SysAllocString(L"System.IO.FileStream"); pAppDomain->CreateInstance_3(assemblyName, typeName, VARIANT_TRUE, BindingFlags_Default, NULL, pArgs, NULL, NULL, NULL, &result);
这对于我尝试创建的所有其他类型都适用;例如

MemoryStream

。但 
FileStream
 特别让我难住了,似乎是因为 
FileStream
 期望在其构造函数中输入 
Enum
 类型(例如 
System.IO.FileAccess
)。如果我尝试给它一个 
VT_I4
 (枚举的基本类型)来代替 
FileAccess
 参数,它会抱怨它找不到构造函数(
HRESULT
COR_E_MISSINGMETHOD
) - 这确实有道理......但鉴于枚举是值类型,没有明显的 VARIANT 类型可供使用。

当某些参数是枚举时,有没有办法在使用托管 CLR 的上下文中使用反射来调用任意构造函数/方法?

c++ .net reflection com clr
1个回答
0
投票
确实,常量需要“装箱”;将它们作为整数传递失败。在编写访问 .NET 的低级库时,我找到了一种方法来做到这一点。对我有用的是在运行时生成常量:

  • 生成编译器对象

  • 编译并运行下面的代码以生成一个包含具有 Box 方法的 BoxHelper 对象的程序集,

  • 创建一个 BoxHelper 对象并在其上调用 Box(程序集名称、常量类型名称、常量值) 在你的情况下,类似: myBoxHelper.Box("mscorlib", "System.IO.FileAccess", 1) 具有以下值:

    文件访问_读取 = 1, 文件访问_写入 = 2, 文件访问_读写 = 3

发送给编译器的源代码: “使用系统;使用System.Reflection;使用System.Runtime.InteropServices;公共类BoxHelper {public IntPtr Box(字符串assem,字符串typ,int值){Type t = Type.GetType(typ); if(t == null ){Assembly a=Assembly.LoadWithPartialName(assem); t = a.GetType(typ);}; return Marshal.GetIUnknownForObject(Enum.ToObject(t,valu));}}"

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.