在Databricks PySpark Notebook中用clr调用C# DLL遇程序集引用问题
在Databricks PySpark Notebook中调用C# DLL的问题
我需要在Databricks的PySpark Notebook里用pythonnet的clr方法运行C#编写的DLL,但始终无法确定正确的程序集名称/.NET引用方式。已确认DLL文件路径正确,尝试过用「Namespace.Class.Function」格式和直接文件路径,拼写均无错误,但多次尝试都报错。
操作步骤
1. 安装依赖
!pip install pythonnet %sh sudo apt-get update sudo apt-get install -y mono-complete %sh echo '#!/bin/bash sudo apt-get update sudo apt-get install -y mono-complete' > conf/install_mono.sh
2. 调用DLL的Python代码
import os import clr import sys # 设置环境变量 os.environ["PYTHONNET_PYDLL"] = "dbfs:/FileStore/shared_uploads/ptgkahoot@gmail.com/SampleClassLibraryProject.dll" # 添加.NET程序集引用(此处出错) clr.AddReference("SampleClassLibraryProject") # 设置.NET运行时路径 sys.path.append("/Users/admin/anaconda3/lib/python3.11/site-packages") # 替换为Python路径 # 导入模块 from SampleClassLibraryProject.Algebra import Addition # 测试调用 result = Addition.Add(2, 3) print(result)
问题详情
- 错误信息:无法加载程序集「SampleClassLibraryProject」或其依赖项,提示找不到指定的文件。
- 文件路径:DLL已上传至
dbfs:/FileStore/shared_uploads/ptgkahoot@gmail.com/SampleClassLibraryProject.dll,路径确认有效。
解决方案
1. 修正PYTHONNET_PYDLL环境变量
PYTHONNET_PYDLL指向的是pythonnet的绑定库(如libpythonnet.so),而非你的业务DLL。先找到Databricks环境中该文件的路径:
!find / -name "libpythonnet.so"
然后设置正确路径,例如:
os.environ["PYTHONNET_PYDLL"] = "/databricks/python/lib/python3.10/site-packages/pythonnet/libpythonnet.so"
2. 将DBFS上的DLL复制到本地文件系统
Databricks的DBFS路径无法直接被mono/pythonnet访问,需复制到本地临时目录:
dbutils.fs.cp("dbfs:/FileStore/shared_uploads/ptgkahoot@gmail.com/SampleClassLibraryProject.dll", "file:/tmp/SampleClassLibraryProject.dll")
3. 正确添加程序集引用
将DLL所在的本地目录加入sys.path,再用完整本地路径或程序集名称添加引用:
sys.path.append("/tmp") # 方式1:用完整本地路径 clr.AddReference("/tmp/SampleClassLibraryProject.dll") # 方式2:用程序集名称(需确保程序集在mono搜索路径,可通过monodis命令验证) # clr.AddReference("SampleClassLibraryProject")
4. 修正sys.path设置
不要添加Anaconda的路径,Databricks使用自有Python环境,只需添加DLL所在的本地目录(如/tmp)。
修正后的完整代码
import os import clr import sys # 复制DBFS中的DLL到本地临时目录 dbutils.fs.cp("dbfs:/FileStore/shared_uploads/ptgkahoot@gmail.com/SampleClassLibraryProject.dll", "file:/tmp/SampleClassLibraryProject.dll") # 添加本地DLL目录到sys.path sys.path.append("/tmp") # 设置pythonnet绑定库路径(根据实际查找结果调整) os.environ["PYTHONNET_PYDLL"] = "/databricks/python/lib/python3.10/site-packages/pythonnet/libpythonnet.so" # 添加程序集引用 clr.AddReference("/tmp/SampleClassLibraryProject.dll") # 导入目标类 from SampleClassLibraryProject.Algebra import Addition # 测试调用 result = Addition.Add(2, 3) print(result)
额外注意事项
- 集群初始化脚本:mono安装需加入集群初始化脚本,否则集群重启后会失效。将安装命令写入
conf/install_mono.sh,并在集群配置中指定该脚本。 - DLL框架兼容性:若DLL基于.NET Core/.NET 5+开发,需使用dotnet运行时而非mono,同时设置
DOTNET_ROOT环境变量。 - 验证程序集名称:用mono工具查看DLL的程序集名称,确保与引用名称一致:
%sh monodis --assembly /tmp/SampleClassLibraryProject.dll
内容的提问来源于stack exchange,提问作者Denis Gojinetchi
相关产品推荐
相关产品推荐

