成员在另一个模块中声明,需要导入

2024-02-05

我使用 Mono.Cecil 创建新的自定义属性类型,然后将其添加到现有类型。

为了演示它,我有一个名为“Sample”的预先存在的 DLL,其类型称为“SampleType”。

我想使用 Mono.Cecil 在“Sample”中编织一个名为“NewAttribute”的新类型,然后将此属性添加到“SampleType”。

代码如下所示:(不完全是这样,但举例来说已经足够好了)

static void AddCustomeAttribute()
{
    var module = ModuleDefinition.ReadModule(AssemblyName);
    var attrType = NewAttributeProvider.Add(module);
    var ctor = attrType.GetConstructors().First();
    //module.Import(ctor);
    CustomAttribute attribute = new CustomAttribute(ctor);
    attribute.ConstructorArguments.Add(new CustomAttributeArgument(module.TypeSystem.String, "InternalClass"));
    module.CustomAttributes.Add(attribute);
    module.Write(AssemblyName); //error
}

-

public static TypeDefinition Add(ModuleDefinition targetModule)
{
    var type = targetModule.AddType("Namespace", "NewAttribute", TypeAttributes.Public | TypeAttributes.Class, targetModule.Import(typeof(Attribute)));
    var stringType = targetModule.TypeSystem.String;
    var nameField = type.AddField(stringType, "_name");
    var nameProp = type.AddSimpleProperty(stringType, "Name", nameField);

    // generate a constructor body
    var constructor = type.AddConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, targetModule.TypeSystem.Void, new[] { stringType });
    constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
    constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1));
    constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Stfld, nameField));
    constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

    var attrUsageType = targetModule.Import(typeof(AttributeUsageAttribute)).Resolve();
    //var att = targetModule.Import(typeof(AttributeUsageAttribute));
    //targetModule.Import(attrUsageType);
    var attributeTargetsType = targetModule.Import(typeof(AttributeTargets));
    //targetModule.Import(attributeTargetsType);
    var propertiesToSet = new Dictionary<string, Tuple<TypeReference, object>>
    {
        {"AllowMultiple", Tuple.Create(targetModule.TypeSystem.Boolean, (object)true)}
    };
    var usageAttr = type.AddCustomAttribute(attrUsageType, new[] { attributeTargetsType }, propertiesToSet);
    //targetModule.Import(usageAttr.AttributeType);
    targetModule.Types.Add(type);
    return type;
}

-

public static CustomAttribute AddCustomAttribute(this TypeDefinition type, TypeDefinition attrType, TypeReference[] ctorParameters, Dictionary<string, Tuple<TypeReference, object>> propetiesToSet)
{
    var attrUsageCtor = attrType.GetConstructors().Single(ctor => ctor.Parameters.Count == ctorParameters.Length && ValidateParameters(ctor.Parameters, ctorParameters));
    type.Module.Import(attrUsageCtor);
    Collection<CustomAttributeNamedArgument> properties = new Collection<CustomAttributeNamedArgument>();
    foreach (KeyValuePair<string, Tuple<TypeReference, object>> typeReference in propetiesToSet)
    {
        properties.Add(new CustomAttributeNamedArgument(typeReference.Key, new CustomAttributeArgument(typeReference.Value.Item1, typeReference.Value.Item2)));
    }
    var customeAttr = new CustomAttribute(attrUsageCtor);
    foreach (var property in properties)
    {
        customeAttr.Properties.Add(property);
    }
    type.CustomAttributes.Add(customeAttr);
    return customeAttr;
}

如您所见,代码中的注释是我为解决问题所做的尝试,但没有成功。 我确信我错过了一些东西,但我不知道是什么..


Cecil 中的 Import 方法具有以下签名:

TypeReference Import(TypeReference type)
MethodReference Import(MethodReference method)

Import接受类型或方法,无论它们在哪里定义,并为它们创建引用对于当前模块。如果您不使用它们返回的内容,则您的代码不正确。

例如,你写:

var attrUsageCtor = attrType.GetConstructors().Single(ctor => ...);
type.Module.Import(attrUsageCtor);

在这种情况下,您正在创建一个CustomAttribute对于您的模块,但使用中定义的构造函数mscorlib。相反,您需要在模块中为构造函数创建一个引用并使用该引用:结果Import是创建自定义属性时必须使用的内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

成员在另一个模块中声明,需要导入 的相关文章

  • CMake 找不到请求的 Boost 库

    既然我已经浏览了其他人的解决方案几个小时 但找不到适合我的问题的正确答案 我想将我的具体问题带给您 我正在尝试使用 CMake 构建 vsomeip 为此 我之前构建了 boost 1 55 但是 我在 CMake 中收到以下错误 The
  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • 检测wlan是否关闭

    任何人都可以给我一个提示 如何在 Windows Phone 上以编程方式检测 C 8 1 应用程序 不是 8 0 是否启用 禁用 WLAN 我不想更改这些设置 只是需要知道 该解决方案是一个 Windows 8 1 通用应用程序 Wind
  • linq 中使用字符串数组 c# 的 'orderby'

    假设我有一个这样的方法定义 public CustomerOrderData GetCustomerOrderData string CustomerIDs var query from a in db Customer join b in
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • 一元 +/- 运算符如何可能导致“-a”或“+a”中的整数提升,“a”是算术数据类型常量/变量?

    这句看似微不足道的台词摘自我的迈克 巴纳汉和布雷迪的 C 书 第 2 8 8 2 节 http publications gbdirect co uk c book chapter2 expressions and arithmetic h
  • 在 omp 并行 for 循环中使用 unique_ptr 会导致 SEG.FAULT

    采取以下代码 include
  • 访问 ascx 文件中的母版页控件

    我有一个母版页文件 其中包含 2 个面板控件中的 2 个菜单 我还使用控件来检查用户是否登录并获取用户类型 根据我想要显示 隐藏面板的类型 控件本身不在母版页中引用 而是通过 CMS 系统动态引用 我想在用户控件中使用findcontrol
  • 将接口转换为其具体实现对象,反之亦然?

    在 C 中 当我有一个接口和几个具体实现时 我可以将接口强制转换为具体类型 还是将具体类型强制转换为接口 这种情况下的规则是什么 Java 和 C 中都允许这两个方向 向下转型需要显式转型 如果对象类型不正确 可能会抛出异常 然而 向上转换
  • 搜索实体的所有字段

    我正在尝试在客户数据库上实现 多功能框 类型的搜索 其中单个查询应尝试匹配客户的任何属性 这是一些示例数据来说明我想要实现的目标 FirstName LastName PhoneNumber ZipCode Mary Jane 12345
  • 为什么 Cdecl 调用在“标准”P/Invoke 约定中经常不匹配?

    我正在开发一个相当大的代码库 其中 C 功能是从 C P Invoked 的 我们的代码库中有很多调用 例如 C extern C int stdcall InvokedFunction int 使用相应的 C DllImport CPlu
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • 如何停止无限循环?

    我正在编写一个程序 该程序将计算三角形或正方形的面积 然后提示用户是否希望计算另一个 我的代码已经运行到可以计算任一形状的面积的程度 但随后不再继续执行代码的其余部分 例如 如果选择了正方形 则计算面积 然后返回到正方形边长的提示 我假设这
  • CUDA 8 编译错误 -std=gnu++11

    我正在尝试转换一些代码以使用 CUDA 并且我认为我遇到了兼容性问题 我们使用CMake 这些是我使用的 gcc 和 CUDA 版本 gcc version gcc Ubuntu 5 4 0 6ubuntu1 16 04 5 5 4 0 2
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • 通过 Tab 键浏览 XML 文档字段

    In VB NET you can move through the fields in the XML member documentation with the Tab key 这在 C 中不起作用 还有其他方法吗 除了用鼠标将光标放在
  • 使用未分配的局部变量

    我遇到了一个错误 尽管声明了变量 failturetext 和 userName 错误仍然出现 谁能帮帮我吗 Use of Unassigned local variable FailureText Use of Unassigned lo

随机推荐