2

I would like to use a function from a given C++ 64 bit shared library (a .so file under linux) from python 2.7.8 .

The header of the C++ shared library has this function:

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

I need a solution that do not require to modify the C++ code of the shared library (a complete Python wrapper already exist with a custom library).

Here is a working solution based on the answer below:

>>> 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

And here is an other way to write it:

>>> 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
Togh
  • 123
  • 1
  • 6
  • `ctypes` should work just fine. Have you set the `argtypes` and `restype` of the function? Why not share how you set up your function in python and what happened when you tried to call it. – Dunes Feb 21 '15 at 10:02
  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself." – Antti Haapala -- Слава Україні Feb 21 '15 at 10:05
  • @Dunes @Antii I updated the question. You are right, that may be more a problem about `argtypes`. – Togh Feb 21 '15 at 10:21
  • I thought it was a problem about conventions different with 32 and 64 bits, but it seems not. The question thus become a duplicate of http://stackoverflow.com/q/145270 – Togh Feb 21 '15 at 14:10

1 Answers1

2

ctypes will do a lot of the type coercion for you.

For instance, given the function strchr defined in string.h

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

You can provide the argument types and return type of the function and not have to bother doing any of the type coercion yourself -- the ctypes module will handle this for you. The only exception is when you need to pass a char * as an out (mutable) argument. Use ctypes.create_string_buffer to create this argument, and access the contents using the value attribute.

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"

Note how ctypes automatically converts the string arguments into the appropriate types, and is able to convert the return value back to a python string.

Dunes
  • 37,291
  • 7
  • 81
  • 97
  • 1
    You are working with the nightly build of library, whose [documentation](http://www.coolprop.dreamhosters.com:8010/binaries/sphinx/_static/doxygen/html/namespace_cool_prop.html#ab79d4586d3575d3b4b0e26bb2825c9de) says the function takes `std::string` parameters not `char *` -- which would explain the segfault. However, there exist python bindings for this library. Why not just use them -- http://sourceforge.net/projects/coolprop/files/CoolProp/5.0.7/Python/ – Dunes Feb 21 '15 at 14:16
  • Sorry, did not saw this comment. When exporting the function, it takes a `char *` before converting to a `std::string`. The full python binding uses directly the C++ function with `std::string`, but I needed to make some quick test wrapper to test the shared library. Accessing this way was only for testing purposes. (I had a strange crash when accessing the library from an other wrapper, I needed to have an other reference to see at which level the problem was. At he end the problem was in the deb packaging of the software used with the other wrapper) – Togh Jun 29 '16 at 15:41