Python for .NET:如何使用同名无版本不同DLL显式创建C#类实例?
解决Python.NET加载同名无版本多DLL的问题
我之前也踩过这个坑!Python.NET的clr.AddReference会跟着CLR的程序集加载规则走,同名且没加强名称/版本号的DLL会被判定为同一个,哪怕路径不一样也没用。要彻底区分开它们,得绕开自动导入,手动加载每个DLL再用反射操作。
步骤1:手动加载不同路径的DLL
别用clr.AddReference,直接用System.Reflection.Assembly.LoadFrom加载每个DLL——CLR会根据加载路径把它们当成独立的程序集,不会混在一起。
示例代码:
import clr # 加载第一个版本的DLL asm_v1 = clr.System.Reflection.Assembly.LoadFrom('c:\\Test\\ModuleV1.dll') # 加载第二个同名称但不同路径的DLL asm_v2 = clr.System.Reflection.Assembly.LoadFrom('c:\\Test\\ModuleV2.dll')
步骤2:通过反射操作类型和方法
加载完程序集后,就可以从每个程序集里拿到对应的类型,不管是静态类还是结构体都能处理:
调用静态类的方法(比如你的SomeClass.SomeMethod)
# 从第一个DLL里获取SomeClass类型 some_class_v1 = asm_v1.GetType('SomeNamepace.SomeClass') # 直接调用静态方法 some_class_v1.SomeMethod(...) # 从第二个DLL里拿同名的SomeClass some_class_v2 = asm_v2.GetType('SomeNamepace.SomeClass') # 调用这个DLL里的SomeMethod some_class_v2.SomeMethod(...)
创建结构体实例(比如SomeStruct)
# 获取第一个DLL的SomeStruct类型 struct_type_v1 = asm_v1.GetType('SomeNamepace.SomeStruct') # 如果结构体有带参数的构造函数,直接传参创建 struct_v1 = struct_type_v1(...) # 无参构造的话直接实例化 struct_v1 = struct_type_v1() # 第二个DLL的结构体同理 struct_type_v2 = asm_v2.GetType('SomeNamepace.SomeStruct') struct_v2 = struct_type_v2(...)
额外提示
- 一定要用绝对路径传给
LoadFrom,避免路径解析出错。 - 如果方法有重载,得指定具体的参数类型来获取对应重载,比如:
# 获取接受int和string参数的SomeMethod重载 target_method = some_class_v1.GetMethod('SomeMethod', [clr.GetType(int), clr.GetType(str)]) # 静态方法Invoke的第一个参数传None,后面是方法参数 target_method.Invoke(None, (123, "hello")) - 这种方式虽然比直接导入麻烦,但能彻底解决同名DLL的冲突问题,完全独立使用每个DLL里的类型。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

