2013-04-29 2 views
0

У меня есть Python C Extension DLL с расширением pyd, который я хотел бы загрузить на Java через System.loadLibrary на windows. Кажется, что нет никакой возможности загрузить DLL с расширением, отличным от * .dll.Загрузить Python C Extension DLL, используя System.loadLibrary

Есть ли предлагаемый подход для решения этой проблемы?

Use Case

Я планирую встроить Python в Java. Я создал расширение DLL, которые я загружал в JAVA, используя JNI для связи с расширением DLL, которые в свою очередь взаимодействует с Python Runtime Environment для выполнения заявления Python

_____      _____   _____ 
| J | System.loadLibrary | |   | P | 
| A |-------------------->| P |   | Y | 
| V |      | Y |<-------->| T | 
| A |  JNI   | D |   | H | 
|___|<------------------->|___|   | O | 
             | N | 
             |___| 
+0

Единственное, о чем я могу думать, было бы либо переименуйте файл, чтобы он имел расширение '.dll', или создайте копию с расширением' .dll'. Однако, кажется, немного странно загружать '.pyd' в Java. Что такое прецедент? – Aya

+0

@Aya: Использовать случай, обновленный в вопросе – Abhijit

+0

@downvoter: Пожалуйста, объясните – Abhijit

ответ

4

Вы пробовали с помощью System.load() вместо этого? Вы можете указать любое имя файла, которое вы хотите, но недостатком является то, что вам нужен полный путь к файлу .pyd.


Это не трудно искать пути, что .dll будет загружены из:

for (String s: System.getProperty("java.library.path").split(";")) { 
    String pydName = s + "/mypythonlib.pyd"; 
    File pydFile = new File(pydName); 
    if (pydFile.exists()) { 
     System.load(pydName); 
     break; 
    } 
} 
+1

'Недостатком является то, что вам нужен полный путь к файлу .pyd. ', Поэтому я не пробовал – Abhijit

+0

+1 Это, казалось бы, ответит на вопрос , –

+0

@DavidHeffernan: Не могли бы вы объяснить, как он отвечает на вопрос? – Abhijit

1

Ну, если вы просто хотите, чтобы запустить код Python в Java, то Jython позволит вам компилировать Исходный код Python в Java .class bytecode, но вы не сможете использовать любую функциональность CPython, которая использует модули расширения.

Если вам действительно нужно встроить CPython в Java, тогда «импорт» файла .pyd не поможет вам. A .pyd будет работать только правильно, если интерпретатор Python уже был инициализирован вызовом Py_Initialize().

Что вам нужно сделать, это посмотреть на CPython embedding docs и использовать JNI для вызова базовых функций CPython в соответствии с примерами в этих документах.

Update

Похоже, что у вас есть один .dll файл, который выступает в качестве модуля расширения, но также предоставляет некоторые символы, которые вы используете, чтобы встроить Python в Java. Если вы никогда не планируете импортировать его в CPython, просто переименуйте его в .dll.

Если вам нужно импортировать его в CPython, то вам, вероятно, следует разделить функциональность на два отдельных файла .dll - тот, который вы используете в встраивании JNI, а другой - как модуль расширения.

+0

У Jython, к сожалению, есть много ограничений esp при попытке использовать ctypes, которые в свою очередь будут иметь проблемы с импортом множества библиотек, использующих ctypes. Во-вторых, связанный документ очень общий, и часть его я сделал, чтобы сделать интерфейс между C и Python. Кроме того, как вы упомянули в комментарии, когда я переименовал 'pyd' в' dll', он работает как шарм. Таким образом, единственная часть, которая создает проблему, - это проблема, упомянутая в вопросе. – Abhijit

+0

@Abhijit Это почти похоже на то, что ваш файл '.pyd' на самом деле предоставляет больше методов, чем требуется для того, чтобы он функционировал как' .pyd'. Оставляет ли он даже символы, необходимые для его импорта в CPython? – Aya

+0

В настоящее время я не планирую импортировать в Python напрямую, но теоретически я могу, затем снова бит: «Он даже разоблачает символы, необходимые для его импорта в CPython», как это повлияет на мое дизайнерское решение? Вы не хотите сделать вывод, что я не должен делать это pyd в первом случае? Уверенно говоря, я слишком созерцаю это, но это создаст еще одну проблему, например, при создании pyd через distutil, который по умолчанию генерирует pyd, а не dll. – Abhijit

1

См. Calling Python in Java?. В принципе, вы используете org.python.util.PythonInterpreter для вызова Python или Jython. Другое возможное решение - использовать файл .so в стиле UNIX. Еще одним выбором может быть использование получения текущего пути, объединение его с именем файла .pyd и использование System.load(), как указано Markku K.

+0

Пожалуйста, обратитесь к комментарию к ответу @ Aya, чтобы понять, почему Jython не будет работать для меня. – Abhijit

+0

@Abhijit: Ваш лучший вариант, вероятно, использовать 'System.load()' следующим образом: 1.Выполнить текущий каталог ('System.getProperty (« user.dir »)). 2. Соедините текущий каталог с именем библиотеки ('full_path = current_dir + name_of_module'). 3. Загрузите полный путь с помощью 'System.load()'. – refi64

Смежные вопросы