当前位置: 首页 > 面试题库 >

适用于.NET的Python:如何使用同一DLL的不同版本显式创建C#类的实例?

滑骞尧
2023-03-14
问题内容

我有一个.cs文件,例如

namespace SomeNamepace
{


    public struct SomeStruct
    {
        ....
    }

    public static class SomeClass
    {
        ....
    }

到目前为止,我将其与PythonNET一起使用

import clr
clr.AddReference('c:\\Test\Module.dll')
from SomeNamepace import SomeClass, SomeStruct

SomeClass.SomeMethod(...)

我的问题是,现在我需要使用名称相同且未设置版本号的dll,因此PythonNET不会将它们视为两个不同的dll,而是相同的。即使我使用带有AddReference的完整路径导入它们。

现在,我想按此处所述明确使用它们:

适用于.NET的Python:在多个版本中使用相同的.NET程序集

喜欢

lib = clr.AddReference('c:\\Test\Module.dll')

我尝试了很多事情来创建SomeClasslike的实例

lib.SomeNamespace.SomeClass()

要么

import System
System.Activator.CreateInstance(lib.GetType('SomeNamespace.SomeClass'))

或使用方法InitializeCreateInstance

或如以下链接中所述

from System import Type
type1 = lib.GetType('SomeNamespace.SomeClass')
constructor1 = type1.GetConstructor(Type.EmptyTypes)

最后一切都失败了,找不到东西,没有方法,等等。

正确的语法是什么?


问题答案:

我发现一个古老的邮件列表对话可能会解释它

如果您需要加载一个特定程序集的多个版本(或者更可能的是,您依赖某个库的话),事情就会变得更加复杂。

在这种情况下,您通过CLR模块访问的名称将始终来自所加载程序集的第一个版本(它将始终在运行时的内部赢得胜利)。

那里发布的解决方案不再起作用,我猜想.NET功能已被弃用。但是有解决方案。代替使用PythonNet,必须直接使用.NET框架:

import System

dll_ref = System.Reflection.Assembly.LoadFile(fullPath)
print(dll_ref.FullName)
print(dll_ref.Location)

检查是否使用了正确的DLL。

要使用具有相同版本的多个DLL,只需将其加载到另一个变量中

another_dll_ref = System.Reflection.Assembly.LoadFile(anotherFullPath)

现在,您可以使用来自指定dll的对象。

公共非静态类的实例

some_class_type = dll_ref.GetType('MyNamespace.SomeClass')
my_instance = System.Activator.CreateInstance(some_class_type)
my_instance.a = 4 # setting attribute
my_instance.b('whatever') # calling methods

在公共静态类中调用方法

some_class_type = dll_ref.GetType('MyNamespace.SomeClass')
method = some_class_type.GetMethod('SomeMethod')
# return type and list of parameters
method.Invoke(None, [1, 2.0, '3'])

创建一个结构实例

some_struct_type = dll_ref.GetType('MyNamespace.SomeStruct')
my_struct = System.Activator.CreateInstance(some_struct_type)
my_struct.a = 3

从LoadFile上的文档

使用LoadFile方法可加载和检查具有相同标识但位于不同路径中的程序集.LoadFile不会将文件加载到加载源上下文中,也不会像LoadFrom方法那样使用加载路径解析依赖项。在这种有限的情况下,LoadFile很有用,因为不能使用LoadFrom加载具有相同标识但路径不同的程序集。它只会加载第一个这样的程序集。

无效的方法:

  • dll_ref = clr.AddReference(f)即使使用显式指定了文件名dll_ref并且使用Reflection来获取方法,也无法添加对使用不同版本的其他DLL的引用。

  • 使用长名称(例如'MyNamespace, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null'使用System.Reflection.Assembly.Load的版本)仍将使用第一个版本

  • System.Reflection.Assembly.LoadFrom如果已经加载了具有相同标识的程序集,则不适用于同一DLL的多个版本。即使指定了其他路径,LoadFrom也会返回加载的程序集。(Doc LoadFrom)



 类似资料:
  • 我通过选择构建变体到来运行代码。然而,运行结果显示,分级程序仍然从中选择类(和),而不是在中使用更改后的版本。 我是不是漏掉了什么?

  • 对不起,如果这是一个微不足道的问题,我是新的指南。假设我有下面这个类: 然后在其他地方我想做: 我希望有两个“MyClass”实例,一个名为“foo ”,一个名为“bar ”(也就是说,它们中的每一个都有一个不同的依赖实例)。我如何将这两个实例添加到我的注入器中,如何用“injector.getInstance”检索它们中的每一个? 我不想为每个可能的依赖项创建一个“MyClass”的子类。 谢谢

  • 问题内容: 我已经安装了Java6和7,并使用eclipse编写了一个简单的jdbc应用程序。我在lib文件夹中同时有sqljdbc4.jar和sqljdbc.jar。我收到此消息… 2013年12月18日9:29:51 com.microsoft.sqlserver.jdbc.SQLServerConnection 严重:该驱动程序不支持Java Runtime Environment(JRE)

  • 问题内容: 如何在网络驱动程序中设置Firefox版本?我只想使用其他版本的Firefox。 就像其他版本19、20、21 … 请提供一个通用解决方案,该解决方案也对其他浏览器有所帮助。 问题答案: 您必须在系统上安装所有版本。然后,您可以使用System属性来定义Firefox的路径。请注意,由于路径是通过System属性设置的,因此您将无法在同一Java进程中运行两个不同的Firefox。 此

  • 问题内容: 我有一个目前使用python 2.5.4运行的系统。我正确安装了,一切正常。我是否可以将与其他版本的Python一起使用? 我编译了Python 2.6.2,并希望将其与一些一起使用。覆盖二进制文件是否足够?还是我必须更改有关库的某些内容? 问题答案: 在创建实例时,只需使用(或)选项来指定要使用的Python可执行文件,例如:

  • 假设我有一个表'some-table',我想在多个模式中创建它。名为“create-some-table.yaml”的文件 最后一个是changelog-master,它非常简单 有什么办法我可以做类似这样的事情吗,谢谢:)