I have just recently started using python for using it with my mfc program and it has been a decent journey so far. At the moment, I am trying to access a function from my mfc dll program that has a format given below:
void DLLDIR DrawEllipse ( CRect, CDC* );
I have used extern "C" and everything and I am able to access the function. In terms of declaring its restype and arguement type, I am facing some problems at the moment. Obviously the restype would be "None" but I am unable to understand as to how do I declare its arguement type which are CRect and CDC*.Would be great if someone already knows how to access the MFC functions and use them as arguements in your python functions.
Thanks in advance.
You can't, you need to wrap those structures as Python objects - either make you own, or use the 'native' Python equivalent of a rectangle (if there is one, I don't know of any). Look at Python win32 packages such as win32all to do the heavy lifting, so that you won't have to re-implement it all yourself.
Related
I am facing some issue with python to java.
I have my python library (test_lib) which have functions (addition, multiply) now I want to use test_lib function in java program but without using (test_lib) in java program. I don't want to show or include function definition in java program. I know if I add python file that have a function I can call in java program but then the user knows the function definition.
Has anyone ever tried python to java. Like with a high level approach?
Thank you.
I am currently working on a usecase where I have implemented APIs in python and they need to return struct, vector and map to C++ caller functions. Could you please help me with an example how to do that. All the usecases I see in pybind/boost python is just simply python being embedded in C++ without any return value.
I came across your blog as well that explained the two libraries pretty well. But I could not proceed because of this usecase.
The scenario which I need to implement is a python -> C++ interface where the C++ caller will start a session and call various python objects when it wants and then close the session. I am ok with solution both in boost::python or pybind11
"All the usecases I see in pybind/boost python is just simply python being embedded in C++ without any return value."
PyBind11 Example with return value
The example the called python function returns an int which they assign first to a py::object and then cast to an int. For STL containers like std::map, std::vector there is automatic conversion if you #include <pybind11/stl.h>. I am unsure about conversion to struct, but I would use one of PyBind's built in STL conversions between Python and C++ and then construct the struct on the C++ side.
I have my own C++ library project(with source) written in Qt and it uses QTcpsocket, QUdpSocket, QSerialPort signals and slots.
I would like to support this library in Python as well.
What is the preferred way to do this?
Writing a wrapper in Python, if so does it have obstacles?
Dont know if PyQt is just for this purpose?
Or do you thnink is it better to rewrite the lib in Python by just implementing the logic used in C++ library project.
As this is library is part of a SDK, same applies for supporting QT dll with .NET as well in fact, as a second step after supporting Python.
Example API of Qt.
quint16 SendCommandAsync(CmdBaseSpv1* pcommand,
ConnectionArg connectionArg,
emitLogOptions::emitLogOption logOption,
LogInfo &txLogInfo,
LogInfo &rxLogInfo);
I want to call this function from Python.
Function parameters CmdBaseSpv1, ConnectionArg, emitLogOption, LogInfo are all Qt classes.
Some of these arguments are using the QOBJECT base class.
As you see from the function name; it is an Asynchronous function call. Result will emit a signal so I need to get async result as well.
I'll write down what I know about wrapping C++ libraries and will try to source it, but as a huge disclaimer, I have only used this for something very, very simple myself.
You ask about rewriting the library in Python. I would say this depends. If the code is trivial, then I don't see why not. If it is larger and has to be kept up-to-date with other code (as you imply with .Net), I wouldn't. It makes sense to reuse the same code for both.
My suggestion
From what I see of your code I would try to wrap it using boost::python or SWIG.
How to wrap
The main trouble is going to be to create CmdBaseSpv1, ConnectionArg, etc. in Python.
If you don't need any Qt-classes to instantiate your classes, this should be straightforward. However, in case you need the Qt types inside of Python (e.g. because the constructor of CmdBaseSpv1 requires a QString), your task is a lot more complicated because you need a way to convert a Python-string into a QString. If you can, you should only use stl-types.
Everything in Python
The simplest way to wrap a small C library is to use the cffi module (or ctypes). You can write the full binding in Python. However, this is a lot of manual work if your API is large and can get difficult.
There is another problem: ctypes is only compatible with C, not C++. So you'd need to change your interface to be compatible with C, internally you could still use C++ and Qt.
Wrap by hand
An alternative is to wrap the library calls yourself. You can either do this by using the Python API. There are also a few libraries that help you create the bindings. Boost::python seems especially promising and works with C++.
Binding generators
If your API is very large, you should use a binding generator which parses the C++ code and generates the bindings itself. For example sip is one of them. It is used to create the bindings for the whole Qt library. There are a few binding generators out there, one mentioned in the Python docs is SWIG. PySide uses Shiboken and also has a nice description of it on their website.
SWIG has the additional advantage, that you can create bindings for multiple languages, including C#.
PyQt
PyQt is a binding generated from Qt using sip. You'll probably not need it, unless you need to access the full power of Qt from inside Python. If this is the case, consider using sipfor generating the bindings, so things like the signal-slot mechanism are compatible between your library and PyQt.
Challenges with bindings
Bindings come with a few challenges because Python and C++ are different in some key areas.
Memory-management
Memory management in Python is almost automatic, in C++ you're required to do it manually. For example
def myfunc():
mywidget = QWidget()
at the end of myfunc() mywidget gets garbage collected. In C++ however
void myfunc() {
auto mywidget = new QWidget();
}
mywidget is still around. This means that even when inside Python, you need to take care of the C++ memory management. The problems I've seen are memory leaks and dangling pointers. Watch out for this when using callbacks, you don't want Python to garbage collect the callback while C++ thinks it's still alive.
Exceptions
Not all programming languages have exceptions or deal with them the same way. For example, it would be nice if an exception inside C++ can be caught inside Python.
Links to related question
How to wrap a c++ library for python? (example of boost::python)
Exposing a C++ API to Python (discussion about boost::python, SWIG and more)
https://stackoverflow.com/a/5686873 (discusses Cython, another choice)
Is there a way to run a c++ class from python without using any external libraries like Boost.Python, SWING ect? I don't want to pass any arguments to this class or call a specific method and in my c++ class I have only a void main method, I just want to run the main and that is all.
Or if this is not possible a saw this tutorial http://intermediate-and-advanced-software-carpentry.readthedocs.io/en/latest/c++-wrapping.html#manual-wrapping. But I didn't understand if I should put the hello_wrapper function in the same c++ class where I have the original hello function. And also how can I create a modulo in Python(second part in the tutorial) and where should I put this code
DL_EXPORT(void) inithello(void)
{
Py_InitModule("hello", HelloMethods);
}
Thanks
is there a way to run a c++ class
you don't run C++ classes. They are data types!
Boost.Python, SWING
It's called SWIG, not SWING :)
You can add your own C wrapper code that initializes a PyObject. I'd recommend reading the CPython docs and the examples in the tutorial on extending python. Since you didn't specify a version, I can't give you a discrete link.
Note that python is C, and C++ isn't; which means that you'll have to export several things with a C ABI, i.e. by using external "C" in your code. That might not be something for the uninitiated, and you should certainly evaluate whether not using external wrapper generators is really worth the trouble – especially since using e.g. SWIG properly (which is really a pain) you can get Python objects that really behave like python objects, e.g. you can extend them with python etc.
I need to call a function written in VB.net as part of my COM automation program.
The VB program requires a byref parameter, defined as
Function GetBeamWidth(ByRef pfBeamWidth As Single) As Integer
I tested the function in VB codes shown below, no problem at all,
Dim y As Single
myObject.GetBeamWidth(x)
'myOject is an instance of the ActiveX server object, which implements function GetBeamWidth
however, I don't have a clue on how to call this function in python. Everything I tried gave me "type not match" error. I am sure that I loaded the ActiveX server, tried early and late binding, tried passing x with the definition of x = [0].
I also tried ctype.byref(x), not working. The example I found online is not that easy to understand. If ctype.byreg is the cure, can someone here paste an easy-to-follow example?
I guess this must be a common problem for yo all experienced programmer out there. I know python doesn't support pointer, but sadly in real life we have to interface with functions written by others/other languages which need passing function parameters by reference.
Thanks in advance!
ByRef is passing by pointer, you can look at ctypes. It also exports byref.
Finally, it turns out to be pretty much impossible to accomplish what I asked for. Alternatively, I wrapped my core functions in Python class and register it as COM server.
Then, I just built the most outside shell in VB.net, which loads all COM servers, provides UI, and simply calls COM functions to do the work.
I guess that is one of reasons for why we have programming platforms other than Python still alive.