I have been using Cython on a couple of projects. I see a lot of documentation on including C++ and C into your cython code. Sometimes when I am extending an existing C/C++ project I feel the urge to code it Python style taking advantage of all the nice features and datatypes. It would be really nice if there was an easy way to ie. call a cython compiled function from C++ or C. Is there an easy way to do this, cause I can't seem to find it in the docs. Or maybe I shouldn't use Cython for this??
Best regards Jakob
I had a more constrained version of your problem and #fabrizioM's answer should work for you:
The trick with cython is in using the keyword public
cdef public double cython_function( double value, double value2 ):
return value + value2
In this way you can link it directly
as a normal C library:
#ifdef __cplusplus {
extern "C"
#endif
double cython_function( double value, double value2 );
#ifdef __cplusplus {
}
#endif
Related
I'm trying to wrap a cpp application and the source code contains the following in a header file
using Time = cppClassDefinition<withT>
...
void setDefaultTime(Time x)
What would be the Cython equivalent for this?
I've tried
cdef extern from "headerfile.h" namespace "ns":
ctypedef cppClassDefinition<withT> Time
to no success. Although Cython does not complain at this step, it throws a compilation error when I try to use the function setDefaultTime(1.0). The error states "Cannot assign type 'double' to 'Time'. In the CPP code however, this seems to be working fine.
I've also tried
cdef extern from "headerfile.h" namespace "ns":
cdef cppclass Time:
pass
and that also failed. Any suggestions? Is this possible using Cython?
As you suggest in the question, you should be able to use use
ctypedef cppClassDefinition[withT] Time
since using ... = ... in this context is equivalent to a typedef. (Note the change to square brackets compared to the code in your question).
I believe the problem is instead with your attempt to do setDefaultTime(1.0). Cython has no way of knowing that double can be converted to Time and there isn't any way of telling it about implicit C++ conversions.
The easiest way round this is to just tell Cython that the function signature is
void setDefaultTime(double x)
(You can leave the C++ signature as is). This will satisfy Cython, and then the C++ code it generates should end up working correctly provided that double can be implicitly converted to Time (as the question implies)
I have a C++ class. It's made up of one .ccp file and one .h file. It compiles (I can write a main method that uses it successfully in c++). How do I wrap this class with Cython to make it available in Python?
I've read the docs and don't follow. They talk about generating the cpp file. When I've tried to follow the docs, my already existing cpp gets blown away...
What am I meant to put in the pyx file? I've been told the class definition but how much of it? Just the public methods?
Do I need a .pxd file? I don't understand when this file is or isn't required.
I've tried asking these question in the #python IRC channel and can't get an answer.
Even Cython is generally for use with C, it can generate C++ code, too. When compiling, you add the --cplus flag.
Now, creating a wrapper for the class is simple and not much different from wrapping a structure. It mainly differs from declaring the extern, but that's not much difference at all.
Suppose you have a class MyCppClass in mycppclass.h.
cdef extern from "mycppclass.h":
cppclass MyCppClass:
int some_var
MyCppClass(int, char*)
void doStuff(void*)
char* getStuff(int)
cdef class MyClass:
# the public-modifier will make the attribute public for cython,
# not for python. Maybe you need to access the internal C++ object from
# outside of the class. If not, you better declare it as private by just
# leaving out the `private` modifier.
# ---- EDIT ------
# Sorry, this statement is wrong. The `private` modifier would make it available to Python,
# so the following line would cause an error es the Pointer to MyCppClass
# couldn't be converted to a Python object.
#>> cdef public MyCppClass* cobj
# correct is:
cdef MyCppClass* obj
def __init__(self, int some_var, char* some_string):
self.cobj = new MyCppClass(some_var, some_string)
if self.cobj == NULL:
raise MemoryError('Not enough memory.')
def __del__(self):
del self.cobj
property some_var:
def __get__(self):
return self.cobj.some_var
def __set__(self, int var):
self.cobj.some_var = var
Note that the new keyword is only available when the --cplus flag is set, otherwise use malloc from <stdlib.h> by externing it.
Also note that you don't need to dereference the pointer (->) to call the method. Cython tracks the object's type and applies what fits.
.pxd files are for seperating declarations from implementation, or to avoid namespace colliding. Imagine you'd like to name you Python-wrapper like the C++ class. Simply put in your .pxd file the extern declarations and cimport the pxd file in the .pyx.
cimport my_pxd
cdef my_pxd.SomeExternedType obj
Note that you can not write implementations in a .pxd file.
So after lots of poking, trial and error, screaming and tearing my hair out, I finally got this to work. First though, I had to re-write my C++ into C, which for me really just involved converting all my std::string variables to char* and keeping track of some lengths.
Once done I had my .h and .c files. I wanted to make a single function from the C code available in Python. It turns out that Cython can compile your C files into the extension for you and link any libraries all in one go, so starting with my setup.py, it ended up looking like this:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules=[
Extension("myext",
["myext.pyx", "../stuff.c"],
libraries=["ssl", "crypto"]
)
]
setup(
name = "myext",
cmdclass = {"build_ext": build_ext},
ext_modules = ext_modules
)
As you can see, the second argument to the Extension simply lists all the files that need to be compiled, Cython works out how to compile them depending on their file extension as far as I can tell. The libraries array tells the Cython compiler what needs to be linked in (in this case I was wrapping some crypto stuff that I couldn't seem to mimick directly through existing Python libs).
To actually make my C function available in the .pyx file, you write a small wrapper in the .pxd. My myext.pxd looked as below:
cdef extern from "../stuff.h":
char* myfunc(char* arg1, char* arg2, char* arg3)
In the .pyx you then use the cimport declaration to import this function, which is then available for use as if it were any other Python function:
cimport myext
def my_python_func(arg1, arg2, arg3):
result = myext.myfunc(arg1, arg2, arg3)
return result
When you build this (on Mac at least) you get a .so that you can import in python and run the functions from the .pyx. There may be better, more correct way to get this all working but that comes from experience and this was a first encounter that I managed to work out. I'd be very interested on pointers where I may have gone wrong.
Update:
After further use of Cython, I found it was super simple to integrate it with C++ too, once you know what you're doing. Making C++'s string available is as simple as from libcpp.string cimport string in your pyx/pyd. Declaring the C++ class is similarly easy as:
cdef extern from "MyCPPClass.h":
cdef cppclass MyCPPClass:
int foo;
string bar;
Sure you have to basically redeclare the .h definition of your class in a Pythonic format, but that's a small price to pay for getting access to your already written C++ functions.
Cython is mainly for C development, to integrate C++ with Python I would recommend Boost.Python. Their excellent documentation should get you started pretty quickly.
The answers above have more or less answered the OP's question.
But its now passing the mid of 2020 and I'd thought to put a contribution (in the form of resource summary) here for those who want to explore Python-C++ bindings via python packages that can be 'pip installed' (or in the PyPI).
I'd reckon for calling C++ from Python / wrapping over third party libs , one can look at cppyy. Its a relatively young project but it certainly looks promising and backed with a modern compiler. See the link below:
https://cppyy.readthedocs.io/en/latest/
Also, there's always pybind11 ....
https://github.com/pybind/pybind11
Cython also supports C++ natively (for most of the C++ languages) ; for more information see https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
is it possible to wrap a c++ library into c?
how could i do this?
are there any existing tools?
(need to get access to a existing c++ library but only with C)
You can write object-oriented code in C, so if it's an object-oriented C++ library, it's possible to wrap it in a C interface. However, doing so can be very tedious, especially if you need to support inheritance, virtual functions and such stuff.
If the C++ library employs Generic Programming (templates), it might get really hairy (you'd need to provide all needed instances of a template) and quickly approaches the point where it's just not worth doing it.
Assuming it's OO, here's a basic sketch of how you can do OO in C:
C++ class:
class cpp {
public:
cpp(int i);
void f();
};
C interface:
#ifdef __cplusplus
extern "C" {
#endif
typedef void* c_handle;
c_handle c_create(int i)
{
return new cpp(i);
}
void c_f(c_handle hdl)
{
static_cast<cpp*>(hdl)->f();
}
void c_destroy(c_handle hdl)
{
delete static_cast<cpp*>(hdl);
}
#ifdef __cplusplus
}
#endif
Depending on your requirements, you could amend that. For example, if this is going to be a public C interface to a private C++ API, handing out real pointers as handles might make it vulnerable. In that case you would hand out handles that are, essentially, integers, store the pointers in a handle-to-pointer map, and replace the cast by a lookup.
Having functions returning strings and other dynamically sized resources can also become quite elaborate. You would need the C caller provide the buffer, but it can't know the size before-hand. Some APIs (like parts of the WIn32 API) then allow the caller to call such a function with a buffer of the length 0, in which case they return the length of the buffer required. Doing so, however, can make calling through the API horribly inefficient. (If you only know the length of the required buffer after the algorithm executed, it needs to be executed twice.)
One thing I've done in the past is to hand out handles (similar to the handle in the above code) to internally stored strings and provide an API to ask for the required buffer size, retrieve the string providing the buffer, and destroy the handle (which deletes the internally stored string).
That's a real PITA to use, but such is C.
Write a c++ wrapper that does an extern c, compile that with c++, and call your wrapper.
(don't “extern c”)
extern C only helps you to have a names in dll like you see them.
You can use
dumpbin /EXPORTS your.dll
to see what happens with names with extern C or without it.
http://msdn.microsoft.com/en-us/library/c1h23y6c(v=vs.71).aspx
To answer your question... It depends... But it is highly unlikely that you can use it without wrappings. If this C++ library uses just a simple functions and types you can just use it. If this C++ library uses a complex classes structure - probably you will be unable to use it from C without wrapping. It is because the internal of classes may be structured one way or another depending on many conditions (using inference with virtual tables or abstracting. Or in example complex C++ library may have its own object creation mechanisms so you HAVE to use it in the way it is designed or you will get unpredictable behavior).
So, I think, you have to prepare yourself for doing dome wrappings.
And here is a good article about wrapping C++ classes. It the article the Author tells about wrapping C++ classes to C# but he uses C at first step.
http://www.codeproject.com/KB/cs/marshalCPPclass.aspx
If the C++ library is written which can be compiled with C compiler with slight editting (such as changing bool to int, false to 0 and true to 1 etc), then that can be done.
But not all C++ code can be wrapped in C. Template is one feature in C++ that cannot be wrapped, or its nearly impossible.
Wrap it in C++ cpp that calls that dll, and "extern C" in that file you made.
Just recently, the GCC 4.6.0 came out along with libquadmath. Unfortunately, GNU has supported Fortran, but not C or C++ (all that is included is a .so). I have not found a way to use these new features in C++, however, GNU C does support the __float128 type for guaranteed quadruple-precision floats. GNU C does not seem to support the math functions in libquadmath, such fabsq (absolute value, q being the suffix for quad).
Is there any way to get these functions working in C++, or is there some alternative library that I could use for math functions with __float128? What is the best method for getting quadruple-precision floats working in the GCC? Right now, I can add, subtract, and multiply them, but this is useless to me, considering how I have no way to convert them to strings or use functions such as truncq and fabsq to create my own string function.
Apparently, this seems to have been an installation error on my part.
While the core C/C++ portion of the GCC includes libquadmath.so, the Fortran version supplies libquadmath.a and quadmath.h, which can be included to access the functions.
#include <quadmath.h>
#include <iostream>
int main()
{
char* y = new char[1000];
quadmath_snprintf(y, 1000, "%Qf", 1.0q);
std::cout << y << std::endl;
return 0;
}
nm the .so file, and see what function names really are. IIRC, fortran routines have an _ at end of name. In C++, you'll need to extern "C" {} prototypes. If this is a fortran interface, then all args are passed by reference, so proto might be something like
extern "C" { long double fabsq_(long double* x); }
I am using SWIG to access C++ code from Python. How do I elegantly wrap a function that returns values in variables passed by reference like
void set(double&a) {
a = 42.;
}
I could not find out how to do this. In the best case I'd be able to use the function in Python with Python floats:
>>> b = 2.
>>> set(b)
>>> print b
42.0
At the moment it gives me a TypeError: in method 'TestDouble_set', argument 2 of type 'double &'.
Do it this way:
Your swig interface file:
%include <typemaps.i>
%apply double& INOUT { double& a };
void set(double& a);
Usage in python script:
a = 0.0
a = set(a)
print a
If your function returns something (instead of being a void), do the below in python
ret, a = set(a)
Checkout the documentation for typemaps in swig. You can do INPUT, OUTPUT & INOUT for arguments. HTH
Note that this solution relies on the SWIG-provided OUTPUT typemaps defined in typemaps.i library, which pre-defines the typemaps being used by the %apply command above.
typemaps.i defines input/output typemaps for C++ primitive types (see the above link to the SWIG documentation for more info); however, you have into include the typemaps.i library in your interface file for SWIG to use them. (Hence why some commenters likely found the original solution wasn't working for them.)
Note that the accepted (correct) solution relies on the SWIG-provided OUTPUT typemaps defined in typemaps.i library, which pre-defines the typemaps being used by the %apply command above.
typemaps.i defines input/output typemaps for C++ primitive types (see the above link to the SWIG documentation for more info); however, you have to include the typemaps.i library in your interface file for SWIG to use them. (Hence why some commenters likely found the original solution wasn't working for them.)
hmm - are you using the latest version of SWIG? The documentation seems to indicate that this works -- from the manual:
C++ references are supported, but SWIG will treat them as pointers. For example, a declaration like this :
class Foo {
public:
double bar(double &a);
}
will be accessed using a function like this :
double Foo_bar(Foo *obj, double *a) {
obj->bar(*a);
}
Functions returning a reference will be mapped into functions returning pointers.
I don't know how you map that on the python side...does python have something like perl references?
It has been very helpful. I recently encountered similar issue, I found this on swig site: (the Return by value part)
I applied it to my interface file (c++ method returning double* -convert it to c#)
it seems working.