Boost.Python and PyQt - pyqt

How do I pass objects like QSize and QPoint between C++ and Python using Boost.Python?

This code worked. I wasn't able to return QSize &c. by internal reference though, but returning by value worked fine.

Related

How to clearly view the object type?

I'm quite a beginner in Python and have been using PyCharm for some weeks.
I'm trying VS Code at the moment and when I'm putting code into the REPL, I wonder if there's a way to display the different objects type ? ... like Pycharm can do in a side frame ;-)
Thank you
You can always return it with the type function.
type(object)

Is it possible to use C++Builder and CMake to create Python modules?

C++Builder's 32-bit compiler, bcc32, by default creates shared libraries using the cdecl calling convention, prefixing exported functions with an underscore,
e.g. '_functionName'. Visual studio, on the other hand, don't prefix exported functions.
Python, when importing a pyd module, expects a function named PyInitialize_modulename. Since bcc32 prefix this function with an underscore, rendering it to be _PyInitialize_modulename, Python will not be able to import a bcc32 created module.
Using CMake, does anyone know how to add a module definition file, .def, to alias the prefixed function, to an 'unprefixed' one, when compiling/creating the pyd module?
Update. In response to Mr. Lebeau's answer below (as a comment);
This question is not about CTypes, but SWIG. CTypes allows for a simple way to wrap a C/C++ DLL, but mainly deals with C structures and POD data.
Swig, on the other hand, allows a client to get object oriented objects in Python, analogous to the ones exported from a C++ DLL. Swig can do this as it process C++ headers.
Swig does create a C++ file that is compiled into a .pyd file (in essence a DLL as noted). The first exported function that Python looks for when trying to load it as a module, is Pyinit_MyModule (Python 3). When using C++ Builder, this function is exported as _Pyinit_MyModule, as mentioned. Problem is that it is Swig that exports this function, and I can't as a client of Swig change the calling convention (afaik) for this function.
I believe my initial belief that Python needed __stdcall for this functions is wrong, as VS by default is using cdecl, but without adding the '_', and it that works fine.
However, setting the compiler flag to suppress underscores don't work either, as then some of the functions in the Python import libraries are rendered invisible, and become unresolved externals. So perhaps this problem is more complex than it may first look. But I guess it has nothing todo with calling conventions.
cdecl is simply the typical default calling convention that every C++ compiler uses. If you want to use stdcall instead, you can certainly do that (makes sense why Python would expect stdcall since that is what the Win32 API uses).
In the module's C++ code, you can use __stdcall explicitly in the exported function declarations.
Or, you can change the default calling convention in C++Builder's project settings, and then omit any calling convention in the function declarations.
Now, to answer your question - when importing a pyd module, if the module uses cdecl, use ctypes.cdll to call its functions. If the module uses stdcall, use ctypes.windll instead. This is covered in Python's documentation:
https://docs.python.org/3/library/ctypes.html#loading-dynamic-link-libraries
16.16.1.1. Loading dynamic link libraries
ctypes exports the cdll, and on Windows windll and oledll objects, for loading dynamic link libraries.
You load libraries by accessing them as attributes of these objects. cdll loads libraries which export functions using the standard cdecl calling convention, while windll libraries call functions using the stdcall calling convention. oledll also uses the stdcall calling convention, and assumes the functions return a Windows HRESULT error code. The error code is used to automatically raise an OSError exception when the function call fails.
https://docs.python.org/3/faq/windows.html#is-a-pyd-file-the-same-as-a-dll
Is a *.pyd file the same as a DLL?
Yes, .pyd files are dll’s, but there are a few differences. If you have a DLL named foo.pyd, then it must have a function PyInit_foo(). You can then write Python “import foo”, and Python will search for foo.pyd (as well as foo.py, foo.pyc) and if it finds it, will attempt to call PyInit_foo() to initialize it. You do not link your .exe with foo.lib, as that would cause Windows to require the DLL to be present.
After some fiddling around, I can say that it is possible to create Python extensions using the C++ Builder compiler, swig and CMake.
Below is a brief overview of the steps that I used to wrap a simple C++ class (ATObject) to Python37.
The C++ header file is:
#ifndef atATObjectH
#define atATObjectH
#include <string>
//---------------------------------------------------------------------------
using std::string;
int MyTest(int r);
class ATObject
{
public:
ATObject();
virtual ~ATObject();
virtual const string getTypeName() const;
};
#endif
and source
#pragma hdrstop
#include "core/atATObject.h"
//---------------------------------------------------------------------------
ATObject::ATObject() {}
ATObject::~ATObject() {}
const string ATObject::getTypeName() const
{
return "TYPENAME NOT IMPLEMENTED";
}
int MyTest(int r)
{
return r;
}
1) Create import libraries using implip on the Python3 and Python37 dll's. Use implibs flag -aa, to get an import library that C++ builder understands. Put them in the Python37/libs folder.
2) Create the swig interface file that defines which class, functions and data to wrap. The swig interface file:
// atexplorer.i
%include "std_string.i"
%include "windows.i"
%module atexplorer
%{
#include "atATObject.h"
%}
//Expose class ATObject to Python
%include "atATObject.h"
3) Create CMake files for the project, using SWIG_ADD_LIBRARY to create the .pyd module, e.g.
SWIG_ADD_LIBRARY(atexplorer MODULE LANGUAGE python SOURCES
atexplorer.i ${ATAPI_ROOT}/source/core/atATObject.cpp )
SWIG_LINK_LIBRARIES (atexplorer
${PYTHON_LIB_FOLDER}/Python3_CG.lib
${PYTHON_LIB_FOLDER}/Python37_CG.lib
)
and make CMake pass the .def file to the linker by adding:
set (CMAKE_MODULE_LINKER_FLAGS ${CMAKE_CURRENT_SOURCE_DIR}/atexplorer.def)
The atexplorer.def file should look like this:
EXPORTS
PyInit__atexplorer=_PyInit__atexplorer
4) Compile the project, and confirm that you get a generated "MyModule"PYTHON_wrap.cxx and a MyModule.py file in your CMake build folder. The "MyModule"PYTHON_wrap.cxx file contains generated C++ code for the Python module, and the .py file contain generated Python code.
The Python module is named atexplorer.
Image below shows what is exported in the _atexplorer.pyd module.
Copy the .pyd and the .py files to Pythons site packages folder.
If successful, you will be able to import the module in Python, e.g.
The screen shot above shows how the module, atexplorer, is imported. It has a function called 'MyTest', that returns whatever its argument is, when executed.
It also has a class, ATObject, for which an object named 'a', is created. Last line prints the output of executing the class member function 'getTypeName()', which simply returns, TYPENAME NOT IMPLEMENTED.

VC++ EXE standalone has bugs that don't happen in IDE

My program has a very specific error that took me a while to track down - now I don't know how to fix it. My code is very long and in many files and I don't see much point in posting it here.
In the IDE, everything runs fine, in both Debug and Release (with the runtime library set to either /MTd or /MT, respectively, so I'm assuming all dependencies are included).
However, when I run the standalone, I get a crash. At first I thought it was a dependency problem but it doesn't seem so.
At some point in the code, I am accessing a vector via a method call: t->GetList(), where GetList is defined as std::vector<T*> & GetList() and the method simply returns a member variable (simply defined as std::vector<T*> field in the class).
It turns out, if I print out the size of the list while running from the IDE, I get 0 (which is the correct answer in this case).
However, when doing the same thing running from standalone, I get the size as 467467353.
I tried changing the method declaration to std::vector<T*> * GetList() and doing return &field; and updating the rest of the code but this didn't fix anything.
I then tried replacing the member variable field with a pointer, and in the constructor instantiating a new vector and deleting it in the destructor. Still no luck.
So I made a simple test case program that simply made a class with a vector field, and a method to return a reference to it. Then in main I would create an instance variable and getting the vector and printing the size. This worked both in VC++ and as a standalone - both returned zero.
This is driving me nuts and I can't figure out why I'm getting different behaviour. Why is the standalone running differently, and what should I be looking at to fix this?
Thanks
Okay so it was literally a bug in my code that was very well hidden. I was dynamically casting to a wrong type.
Somehow it slipped past when I was running on Windows and OSX in both Debug and Release, and as a standalone on OSX. Good thing I found it.

wxString Printf function issues in linux

i am trying to Print some data in wxstring using printf function but its crashing in run time in LINUX but not in windows
here is my code:
wxString str1,str2;
str1 = "Elements";
str2.Printf( _U("%s"),str1);
This is working in windows but not in linux , if i change it below its working in linux also
str2.Printf( _U("%s"),str1.c_str());
why its not taking str1 as argument.
Note:This sentence i am using throughout the workspace is there any common way to do this in linux instead of changing in all places
The only "fix" is to upgrade to wxWidgets 3.0 where wxString::Printf() and other similar functions are (pseudo) variadic templates and so do work correctly with objects and not only raw pointers. In wxWidgets 2.8 they are variadic functions and, according to the language rules, can't work with the objects and no, there is no way around this.
This help clarify you:
The following code:
wxString str;
str.Printf(wxT("My string is %s"), wxString("whatever"));
does not work. Unfortunately, it may seem to work fine under Windows because of a compiler quirk there but passing a wxString object to a function taking a variable number of arguments such as Printf() is undefined behaviour in C++. Accordingly, it will simply crash under most platforms but may even "work" on some of them.
You must use c_str() to make the above code work, i.e. write this instead:
wxString str;
str.Printf(wxT("My string is %s"), wxString("whatever").c_str());
Note that g++ should give you an error when passing an object to a vararg function like this -- another reason to compile your code with g++ even if you normally use another compiler.

What is the function of class ExprRequire in Haxe?

I am new to Haxe was trying to compile a .hx file. This file uses ExprRequire. Is this class deprecated from the latest versions? Everytime, I compile I get class not found ExprRequire. I do not also see any file name ExprRequire.hx at \haxe\std\haxe\macro with haxe versions 2.0.7 and 2.0.8.
If this file is deprecated what class should I be using to replace it. Also if someone could place a simple code that could help me understand the migration from ExprRequire to the other class.
-Kshitiz
Have you tried adding import haxe.macro.Expr; ? As far as I known, ExprRequire is defined within haxe.macro.Expr module. You can read more about modules here.
ExprRequire is found in haxe.macro.Expr. It is actually a replacement for a regular Expr, that includes a type for type completion when using the macro. To use that file, all you should have to do is add import haxe.macro.Expr; to the top of the file with the other imports.

Resources