Этот вопрос довольно длинный, но я стараюсь предоставить вам детали, которые, по моему мнению, необходимы для поиска ответа.
У меня есть решение C # WPF (.Net 4), состоящее из основного проекта, создающего приложение Windows WPF, которое зависит от нескольких проектов библиотек классов, находящихся в одном решении Visual Studio 2010.
Один из проектов библиотеки классов инкапсулирует некоторый ранее разработанный код Python , который я хочу использовать через IronPython и Microsoft Dynamic Language Runtime.
Я хотел бы, чтобы проект библиотеки классов был автономным и не зависел от полной установки IronPython.
Проблема в том, что я не знаю, как ссылаться на инкапсулирующий библиотечный проект, содержащий код Python таким образом, что всегда работает.
Обычно я просто добавляю ссылку на проект библиотеки классов, как обсуждалось в этом вопросе: Visual Studio 2010: Как ссылаться на проект библиотеки классов C # .Net с зависимостями третьей части . Однако это не помогло.
Как настраивается решение в Visual Studio:
Решение выглядит так:
- MainApp (проект приложения Windows WPF)
- ClassLib1 (проект библиотеки классов C #)
- ClassLibWithPython (проект библиотеки классов C # с IronPython)
- C # классы
- lib (каталог)
- IronPython.dll
- IronPython.Modules.dll
- Microsoft.Dynamic.dll
- Microsoft.Scripting.dll
- pylib (каталог с некоторыми используемыми модулями python)
- ctypes (каталог с некоторыми используемыми модулями python)
- Мои классы Pyton (каталог)
ClassLibWithPython содержит ссылки на DLL-библиотеки IronPython, находящиеся в его локальной папке lib (атрибут 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, no os specific module found
) из-за отсутствия имени модуля '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__', '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']
Обходной путь, который не помог
Я пытался добавить операторы using
в код C # ClassLibWithPython, чтобы убедиться, что даже неявно ссылающиеся сборки связаны, но без различий.
Обходные пути, которые помогли
Я нашел два обходных пути, обеспечивающие рабочее решение, однако оба они нарушают принцип инкапсуляции и раскрывают детали реализации ClassLibWithPython:
- Вместо этого поместите весь код из ClassLibWithPython в проект MainApp.
- Храните ClassLibWithPython в отдельном проекте, но добавляйте ссылки на IronPython.dll и IronPython.Modules.dll в проект MainApp.
Что заставляет работать обходной путь № 2?
Какие-нибудь предложения, как сделать эту работу чистым способом?
Спасибо, что прочитали это далеко; -)