如何使用 IronPython 引用独立的 C# 类库项目 (Visual Studio 2010)

发布于 2024-12-13 08:11:37 字数 3053 浏览 2 评论 0 原文

这个问题有点长,但我尝试向您提供我认为找到答案所必需的详细信息。

我有一个 C# WPF 解决方案 (.Net 4),由一个主项目组成,构建一个 WPF Windows 应用程序,它依赖于同一 Visual Studio 2010 解决方案中的一些类库项目。

其中一个类库项目封装了一些以前开发的 python 代码,我想通过 IronPython 和 Microsoft Dynamic Language Runtime 使用这些代码。 我希望类库项目是独立的,而不依赖于 IronPython 的完整安装。

问题是我不知道如何以始终有效的方式引用保存 python 代码的封装库项目。

通常,我只会添加对本问题中讨论的类库项目的引用: Visual Studio 2010:如何引用具有第三方依赖项的 C# .Net 类库项目。然而这并没有帮助。

如何在 Visual Studio 中设置解决方案:

解决方案如下所示:

  • MainApp(Windows WPF 应用程序项目)
    • ...
  • ClassLib1(C# 类库项目)
    • ...
  • ClassLibWithPython(使用 IronPython 的 C# 类库项目)
    • C# 类
    • lib(目录)
      • IronPython.dll
      • IronPython.Modules.dll
      • Microsoft.Dynamic.dll
      • Microsoft.Scripting.dll
      • Microsoft.Scripting.Metadata.dll
      • pylib(包含一些使用的 python 模块的目录)
        • os.py
        • ....py
      • ctypes(包含一些使用的 python 模块的目录)
      • 我的 pyton 类(目录)

ClassLibWithPython 引用了驻留在其本地 lib 文件夹中的 IronPython DLL(Copy Local属性True)。 MainApp 项目引用了 ClassLib1 项目和 ClassLibWithPython 项目(也具有 Copy Local 属性 True)。

编译解决方案时,所有 DLL 和 MainApp.exe 文件都会显示在 MainApp/bin/Debug 中,并且它在某些计算机(XP 和 Win 7)上工作正常,但在其他一些计算机(XP)上失败。经过一些调试后,我发现内置 IronPython 模块未正确加载。导入 os 模块时(像这样的 pylib/os.py http://pydoc.org/get.cgi/usr/local/lib/python2.5/os.py)我得到一个Python异常(ImportError,没有找到操作系统特定模块) 由于缺失模块名称'nt'

当比较它工作的地方和不工作的地方发生的情况时,我发现 sys.builtin_module_names 与我在其他一些机器上运行相同代码时得到的结果相比,只返回了一些项目。

有问题的机器有:

sys.builtin_module_names = ['clr', 'future_builtins', 'imp', 'sys', '__builtin__', 'exceptions']

一切正常的计算机有:

sys .builtin_module_names: ['clr', 'future_builtins', 'imp', 'sys', '__builtin__', '例外','_codecs','cmath','_sha512','msvcrt','数组','_winreg','_weakref','_warnings','_subprocess','_ssl','_sre','_random ', '_functools', 'xxsubtype', '时间', '线程','_struct','_heapq','_ctypes_test','_ctypes','套接字','_sha256','_sha','选择','re','运算符','nt','_md5 ', '数学', '元帅', '_locale', '_io', 'itertools'、'gc'、'errno'、'datetime'、'cStringIO'、'cPickle'、'copy_reg'、'_collections'、'binascii'、'zlib'、'signal'、'mmap']

没有帮助的解决方法

我尝试将 using 语句添加到 C# 代码中ClassLibWithPython 来确保隐式引用的程序集也被链接,但没有区别。

有帮助的解决方法

我发现了两种提供可行解决方案的解决方法,但是它们都打破了封装原则并公开了 ClassLibWithPython 的实现细节:

  1. 将 ClassLibWithPython 中的所有代码放入 MainApp 项目中。
  2. 将 ClassLibWithPython 保留在单独的项目中,但将对 IronPython.dll 和 IronPython.Modules.dll 的引用也添加到 MainApp 项目中。

是什么让解决方法 #2 发挥作用?

有什么建议如何让这项工作以干净的方式进行吗?

感谢您阅读本文;-)

This question is kind of lengthy but I try to provide you with the details that I think is necessary to find the answer.

I have a C# WPF solution (.Net 4) consisting of a main project, building a WPF windows app, which depends on a few class library projects residing in the same Visual Studio 2010 solution.

One of the class library projects encapsulates some previously developed python code that I want to make use of through IronPython and Microsoft Dynamic Language Runtime.
I would like the class library project to be self contained and not depend on a complete installation of IronPython.

The problem is that I don't know how to refer to the encapsulating library project holding the python code in a way that always work.

Normally I would just add a reference to the class library project as discussed in this question: Visual Studio 2010: How refer to a C# .Net class library project with third part dependencies. However it did not help.

How the solution is set up in Visual Studio:

The solution looks like this:

  • MainApp (windows WPF application project)
    • ...
  • ClassLib1 (C# class library project)
    • ...
  • ClassLibWithPython (C# class library project with IronPython)
    • C# classes
    • lib (directory)
      • IronPython.dll
      • IronPython.Modules.dll
      • Microsoft.Dynamic.dll
      • Microsoft.Scripting.dll
      • Microsoft.Scripting.Metadata.dll
      • pylib (directory with some used python modules)
        • os.py
        • ... .py
      • ctypes (directory with some used python modules)
      • my pyton classes (directory)

ClassLibWithPython has references to the IronPython DLLs residing in its local lib folder (Copy Local attribute True). The MainApp project has references to ClassLib1 project and ClassLibWithPython project (also with Copy Local attribute True).

When compiling the solution all DLLs and the MainApp.exe file shows up in MainApp/bin/Debug and it works fine on some machines (XP and Win 7) however it fails on some other machines (XP). After doing some debugging I've found that the built-in IronPython modules are not loaded correctly. When importing the os module (pylib/os.py like this one http://pydoc.org/get.cgi/usr/local/lib/python2.5/os.py) I get a python exception (ImportError, no os specific module found) due to missing module name 'nt'.

When comparing what's happening where it works and where it doesn't I've found that sys.builtin_module_names just returns a few items compared to what I get when running the same code on some other machines.

Problematic machine has:

sys.builtin_module_names = ['clr', 'future_builtins', 'imp', 'sys', '__builtin__', 'exceptions']

Computers where everything works have:

sys.builtin_module_names: ['clr', 'future_builtins', 'imp', 'sys', '__builtin__', 'exceptions', '_codecs', 'cmath', '_sha512', 'msvcrt', 'array', '_winreg', '_weakref', '_warnings', '_subprocess', '_ssl', '_sre', '_random', '_functools', 'xxsubtype', 'time', 'thread', '_struct', '_heapq', '_ctypes_test', '_ctypes', 'socket', '_sha256', '_sha', 'select', 're', 'operator', 'nt', '_md5', 'math', 'marshal', '_locale', '_io', 'itertools', 'gc', 'errno', 'datetime', 'cStringIO', 'cPickle', 'copy_reg', '_collections', 'binascii', 'zlib', 'signal', 'mmap']

Work-around that didn't help

I've tried to add using statements to the C# code of ClassLibWithPython to make sure even the implicitly referenced assemblies are linked, but with no difference.

Work-arounds that helped

I've found two workarounds providing a working solution, however both of them breaks the encapsulation principle and exposes the implementation details of ClassLibWithPython:

  1. Put all code from ClassLibWithPython in the MainApp project instead.
  2. Keep ClassLibWithPython in a separate project but add references to IronPython.dll and IronPython.Modules.dll to the MainApp project as well.

What is it that make work-around #2 working?

Any suggestions how to make this work in a clean way?

Thank's for reading this far ;-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意中人 2024-12-20 08:11:37

我不完全理解部署的布局 - 但请尝试以下操作。

1) 对于您希望从 IronPython.Modules.dll 加载的模块,请确保此程序集在您的部署位置中可用,和/或挂钩 AssemblyResolve (请参阅此处) 事件(如果此程序集位于不同位置)。

2) 对于您希望从 py 模块加载的模块。确保通过 sys 或 DLR 托管 API 将探测位置添加到 sys.path。例如 sys.path.append(...)

I don't fully understand the deployed layout - but try the following.

1) For modules that you expect to be loaded from IronPython.Modules.dll ensure that this assembly is available in your deployment location, and/or hook AssemblyResolve (see here) event if this assembly is in a different location.

2) For modules that you expect to be loaded from a py module. Ensure the probing location is added to sys.path via sys or from the DLR hosting API. eg sys.path.append(...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文