Как ссылаться на автономный проект библиотеки классов C # с IronPython внутри (Visual Studio 2010) - PullRequest
4 голосов
/ 03 ноября 2011

Этот вопрос довольно длинный, но я стараюсь предоставить вам детали, которые, по моему мнению, необходимы для поиска ответа.

У меня есть решение 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)
      • os.py
      • ... .py
    • 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:

  1. Вместо этого поместите весь код из ClassLibWithPython в проект MainApp.
  2. Храните ClassLibWithPython в отдельном проекте, но добавляйте ссылки на IronPython.dll и IronPython.Modules.dll в проект MainApp.

Что заставляет работать обходной путь № 2?

Какие-нибудь предложения, как сделать эту работу чистым способом?

Спасибо, что прочитали это далеко; -)

1 Ответ

1 голос
/ 09 ноября 2011

Я не полностью понимаю развернутый макет - но попробуйте следующее.

1) Для модулей, которые вы ожидаете загрузить из IronPython.Modules.dll, убедитесь, что эта сборка доступна в вашем местоположении развертывания, и / или перехватите AssemblyResolve (см. Здесь) событие, если это сборка находится в другом месте.

2) Для модулей, которые вы ожидаете загрузить из модуля py. Убедитесь, что местоположение зонда добавлено в sys.path через sys или из API хостинга DLR. например, sys.path.append(...)

...