2015-02-21 3 views
2

Я хотел бы использовать функцию из данной 64-битной общей библиотеки C++ (файл .so под linux) из python 2.7.8.Вызов 64-битной общей библиотеки C++ из Python

The header С ++ разделяемой библиотекой имеет эту функцию:

EXPORT_CODE double CONVENTION PropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char *Ref);

Мне нужно решение, которое не требует, чтобы изменить код C++ из общей библиотеки (полный Python обертку уже существует с обычаем библиотека).

Вот рабочий раствор на основе ответа ниже:

>>> import ctypes 
>>> lib = ctypes.cdll.LoadLibrary("/PathTo/libCoolProp.so") 
>>> PropsSI = lib.PropsSI 
>>> PropsSI.argtypes = (ctypes.c_char_p, ctypes.c_char_p, ctypes.c_double, ctypes.c_char_p, ctypes.c_double, ctypes.c_char_p) 
>>> PropsSI.restype = ctypes.c_double 
>>> result = PropsSI(b"H", b"T", 300., b"P", 101325., ctypes.create_string_buffer("Water", 8)) 
>>> result 
112654.89965373254 

А вот другой способ, чтобы написать это:

>>> from ctypes import * 
>>> CoolProp = cdll.LoadLibrary('/PathTo/libCoolProp.so') 
>>> PropsSI = CoolProp.PropsSI 
>>> PropsSI.restype = c_double 
>>> print PropsSI(c_char_p("H"), c_char_p("T"),c_double(300.),c_char_p("P"),c_double(101325.),c_char_p("Water")) 
112654.899654 
+0

'ctypes' должен работать нормально. Установили ли вы 'argtypes' и' restype' функции? Почему бы не поделиться тем, как вы настроили свою функцию на python и что произошло, когда вы пытались ее вызвать. – Dunes

+0

«Вопросы, требующие помощи по отладке (« почему этот код не работает? ») Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для воспроизведения в самом вопросе». –

+0

@Dunes @Antii Я обновил вопрос. Вы правы, это может быть проблемой для 'argtypes'. – Togh

ответ

2

ctypes будет делать много типа принуждения для вас ,

Например, учитывая функцию strchr, определенной в string.h

const char * strchr (const char * str, int character); 

Вы можете предоставить типы аргументов и тип возвращаемого значения функции и не должно беспокоить делать какие-либо из типа принуждения самого - ctypes модуля будет обрабатывать это для вас. Единственное исключение - когда вам нужно передать char * в качестве аргумента out (mutable). Используйте ctypes.create_string_buffer для создания этого аргумента и доступа к содержимому с использованием атрибута value.

import ctypes 

libc = ctypes.cdll.LoadLibrary("msvcrt") 
# or on linux 
# import ctypes.util 
# libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c")) 

strchr = libc.strchr 

strchr.argtypes = (ctypes.c_char_p, ctypes.c_char) 
strchr.restype = ctypes.c_char_p 

result = strchr(b"abcde", b"c") 
assert result == b"cde" 

Обратите внимание, как ctypes автоматически преобразует строковые аргументы в соответствующие типы, и способен преобразовать возвращаемое значение обратно в строку питона.

+1

Вы работаете с ночной сборкой библиотеки, чья [документация] (http://www.coolprop.dreamhosters.com:8010/binaries /sphinx/_static/doxygen/html/namespace_cool_prop.html#ab79d4586d3575d3b4b0e26bb2825c9de) говорит, что функция принимает параметры 'std :: string', а не' char * '- что объясняет segfault. Однако для этой библиотеки существуют привязки python. Почему бы просто не использовать их - http://sourceforge.net/projects/coolprop/files/CoolProp/5.0.7/Python/ – Dunes

+0

Извините, этого не заметил. При экспорте функции перед преобразованием в строку 'std :: string' берется символ' char * '. Полное связывание с python напрямую использует функцию C++ с помощью 'std :: string', но мне нужно сделать небольшую тестовую оболочку для проверки общей библиотеки. Доступ к этому пути был только для целей тестирования. (У меня был странный сбой при доступе к библиотеке из другой оболочки, мне нужно было иметь другую ссылку, чтобы увидеть, на каком уровне возникла проблема. В конце концов проблема заключалась в упаковке deb программного обеспечения, используемого с другой оболочкой) – Togh

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