7

我有一个 .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 的完整路径导入它们。

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

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

喜欢

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

我尝试了很多方法来创建SomeClass类似的实例

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)    

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

这样做的正确语法是什么?

4

1 回答 1

6

我发现了一个可以解释它的旧邮件列表对话

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

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

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

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 的引用 usingdll_ref = clr.AddReference(f)不起作用,即使明确指定了文件名dll_ref并且使用反射来获取方法

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

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

于 2018-04-24T13:36:49.347 回答