Following the different tutorials on the web, I have tried to make a wrapper of a c++ class in python, using SWIG.
My class looks like this:
/*file libraryInstance.h*/
struct LibraryInstance
{
void init();
void terminate();
private:
std::shared_ptr<AnObject> m_spAnObject;
};
For python exposition, I made this .i file:
%module LibraryInstance
%{
#include "libraryInstance.h"
%}
%include "libraryInstance.h"
then I have executed the command swig -c++ -python -o ./src/libraryInstance_wrap.cpp ./src/libraryInstance.i
without any output errors, swig has generated two files, libraryInstance_wrap.cpp and LibraryInstance.py
Then I compile the c++ files, including the libraryInstance_wrap.cpp. All compiles fine and I get my library .so file.
when I look into the swig generated LibraryInstance.py, I can clearly see the class LibraryInstance:
cf. entire generated python wrapper here.
But when I launch the command python LibraryInstance.py, in the same directory as my .so I see this error output:
Traceback (most recent call last):
File "LibraryInstance.py", line 26, in <module>
_LibraryInstance = swig_import_helper()
File "LibraryInstance.py", line 18, in swig_import_helper
import _LibraryInstance
ImportError: No module named _LibraryInstance
And when I look in the code of LibraryInstance.py, it just looks as if there has been an exception ImportError thrown, the the module cannot be found by python. ( line 18 ).
Any idea what should I do to correct this ?
In SWIG documentation, paragraph 31.2.2 it is stated that the name of the library .so should be _NameOfTheModule.so
So I have renammed my library _LibraryInstance.so, instead of LibraryInstance.so... and now my module loads fine.
Related
I want to run my C++ programs using micropython which run on esp-32 board perfectly. Now I want to run it using micropython. For that I am referring to
https://github.com/stinos/micropython-wrap this wrapper.
I created foo.cpp and test.py
#include <micropython-wrap-master/functionwrapper.h>
//function we want to call from within a MicroPython script
std::vector< std::string > FunctionToBeCalled ( std::vector< std::string > vec )
{
for( auto& v : vec )
v += "TRANSFORM";
return vec;
}
//function names are declared in structs
struct CppFunction
{
func_name_def( TransformList )
};
extern "C"
{
void RegisterMyModule(void)
{
//register a module named 'foo'
auto mod = upywrap::CreateModule( "foo" );
//register our function with the name 'TransformList'
//conversion of a MicroPython list of strings is done automatically
upywrap::FunctionWrapper wrapfunc( mod );
wrapfunc.Def< CppFunction::TransformList >( FunctionToBeCalled );
}
}
test.py
import foo
print(foo.TransformList(['a', 'b'])) # Prints ['aTRANSFORM', 'bTRANSFORM']
But whatever way I try it get
ERROR thonny.plugins.micropython.backend: Problem adding Expr handlers
Traceback (most recent call last):
File "/Applications/Thonny.app/Contents/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/thonny/plugins/micropython/backend.py", line 1235, in _add_expression_statement_handlers
root = ast.parse(source)
File "/Applications/Thonny.app/Contents/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py", line 50, in parse
return compile(source, filename, mode, flags,
File "<unknown>", line 1
python test1.py
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "<stdin>", line 1
SyntaxError: invalid syntax
What I understand, before I can run cpp program I need to run makefile. But there is no steps available which explains me how to build makefile using micropython on esp-32
Any help appreciated
The repo you linked to doesn't let you "run" a C++ program from within MicroPython. You cannot just import C or C++ code into MicroPython at runtime, as you were trying to. C and C++ must be compiled using a C/C++ compiler.
The repo you referenced lets you extend MicroPython by compiling your own C++ functions and including them in the MicroPython firmware. To do that you have to rebuild MicroPython itself on a Linux, Mac or Windows computer.
As its README says:
Integrating and Building
First clone this repository alongside the MicroPython repository, then
refer to the way the tests module is built and create your own modules
in the same way.
To use it, you need to clone the MicroPython repo, create your own modules in it, rebuild MicroPython, then re-flash your ESP32 with your new MicroPython firmware.
You can find more information on building MicroPython and on MicroPython modules in the MicroPython repository.
I have been able to implement an algorithm in C++ (error level analysis algorithm for JPEG images) and I have also been able to compile a Python wrapper for the code using cython but at the time of testing it I am facing issues.
This is the Link to my previously asked question containing the source code and all relevant information regarding the following post.
I have created a wrapper function for my C++ code and built it using cython but at the time time of testing I a getting the following error:
Traceback (most recent call last):
File "Test.py", line 1, in <module>
import ela
ImportError: /home/shreyash/Desktop/New/ela.so: undefined symbol:_ZN2cv14createTrackbarERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_PiiPFviPvES9_
There seems to some problem with the createtrackbar symbol in the shared object file which is somehow undefined.
The problem was with configurations of the setup.py file , i just had to expicitly specify all the libraries being used by my opencv implementation.
After compiling with the help of cython it generated a shared object file
which had all the defined symbols.
How do you get started running (and debugging) a C++/Python combined project?
So far I've started with the basics:
Checking out the project from source (http://code.google.com/p/pyv8/source/checkout)
Copying a helloworld.py example into the directory with PyV8, so it can import PyV8.
This doesn't work, of course:
Traceback (most recent call last):
File "helloworld.py", line 4, in <module>
import PyV8
File "C:\Users\Default User\Documents\pyv8-read-only\PyV8.py", line 32, in
<module>
import _PyV8
ImportError: No module named _PyV8
The next step is probably to compile the cpp files and somehow make them available to Python as a library, but I'm not sure how to do that from the command line. There appears to be a VS project but I don't have Visual Studio.
(It would be way more awesome if anyone could also figure out how to debug both the C++ and Python parts in Eclipse)
Help! Thanks.
I'm trying to use boost.python and build a python extension from c++.
My cpp file use a function named 'BZ2_bzopen' which is in the library 'libbz2' under standard path (/usr/lib/). However, when I try to build the extension using boost build following the instruction, I received an error said:
====== BEGIN OUTPUT ======
Traceback (most recent call last):
File "CrossTrade.py", line 11, in <module>
from custom_c import GoThroughFile
ImportError: /home/jliu/toolpak/custom_c.so: undefined symbol: BZ2_bzopen
EXIT STATUS: 1
====== END OUTPUT ======
This seems to me as an error comes from not linking to the library, which is almost the same as if I compile the cpp file without the '-lbz2' command.
Anyone could offer some help on solving it, please?
Maybe you did not link to libbz2? In that case, follow the instructions in http://www.boost.org/doc/libs/1_46_1/doc/html/bbv2/tutorial.html#bbv2.tutorial.prebuilt to see how to link to libraries.
I am trying to port my c++ code to python by swig.
When I finish building the py, pyd, cxx and lib files, under Python (command line), I key in "module Dnld", it shows-> import error:dynamic module does not define init function.
The following is my code,
Further: Add my build step to avoid misunderstanding, thank you Mark Tolonen
File->New->Project->Windows Console Application-> Select DLL and empty project(no unicode)
Add my SerialComm folder to the project(include DownloaderEngine.h Serial.h PortEnumerator.h,etc).
Configuration properties->c/c++->Additional include directories->C:\Python27\include
Configuration properties->Linker->General->Output File->$(OutDir)\Dnld.pyd
Configuration properties->Linker->Input->Additional include directories->C:\Python27 \libs\python27.lib and .\SerialComm\setupapi.lib
Add Dnld.i , do custom build
Dnld.i property page->Command line->swig -c++ -python $(InputPath)
Dnld.i property page->Output->$(InputName)_warp.cpp
build, create Dnld_wrap.cxx, Dnld.py
Add Dnld_wrap.cxx in my project, rebuild all, create Dnld.pyd, that's it
(Enviroment:XP SP3 with VC2008)
//DownloaderEngine.h
class __declspec(dllexport) CDownloaderEngine
{
public:
CDownloaderEngine();
virtual ~CDownloaderEngine();
signed char OpenPort(signed char _ucPort, unsigned long _ulBaudRate, unsigned char _ucParity,
unsigned char _ucStopBits,unsigned char _ucData);
....
};
//DownloaderEngine.cpp
CDownloaderEngine::CDownloaderEngine()
{
....
}
CDownloaderEngine::~CDownloaderEngine()
{
....
}
//DownloaderEngine.i
%module Dnld
%include <windows.i>
%include <std_vector.i>
%include <std_map.i>
%{
#define SWIG_FILE_WITH_INIT
#include ".\SerialComm\DownloaderEngine.h"
%}
/* Parse the header file to generate wrappers */
%include ".\SerialComm\DownloaderEngine.h"
Not really enough information, because the problem is likely in how you are building it. for example, with the files you've specified, building from a VS2008 command prompt should be something like:
swig -python -c++ DownloaderEngine.i
cl /LD /W4 /Fe_Dnld.pyd /Ic:\Python27\include downloaderEngine_wrap.cxx -link /LIBPATH:c:\Python27\libs DownloaderEngine.lib
Edit: Your build steps look about right, but one thing is the .pyd file is expected to be named _Dnld.pyd (note the underscore).
The generated Dnld.py calls import _Dnld (the .pyd), so you will import Dnld (the .py) in your Python script.
Example:
>>> import Dnld
>>> engine = Dnld.CDownloaderEngine()
>>> result = engine.OpenPort(...)
This is the error I get if I rename the .pyd without an underscore:
>>> import Dnld
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initDnld)
So I'm sure this will fix your issue. 我很高興幫助你!
For the record, here another possible cause of the error message
ImportError: dynamic module does not define init function (init<mylibrary>):
Running Python2 while Swig was set up for Python3, or vice versa.
This one took me a while to figure out. From the python.org mailing lists here, it seems the problem is that python expects module Foo to provide a function initFoo. The question then, is why doesn't Dnld provide initDnld. Since swig should handle most of that, it is probably because swig doesn't expect the finished library to be called Dnld (if it expects dnld or D_nld or anything else, it will fail, but renaming the file fixes it.) Note that this applies to any C extension for python, including those generated by pyrex/cython and boost.