how to pass python method and kwargs to boost python c++ function and call

0

how do I pass a python method and kwargs to a boost C++ function and call the python method with kwargs.

python:

def py_method(**kwargs):
    for key in kwargs.keys():
        print 'Key: ', key, ', Value: ', kwargs[key]

cpp_method(py_method, arg1=1, arg2=2)

or

kwargs = {'arg1': 1, 'arg2': 2}
cpp_method(py_method, **kwargs)

C++: please help me to correct the below code.

using namespace boost::python;

void cpp_method(object py_method, object kwargs)
py_method(kwargs)

Thanks to Dan MaĊĦek for pointing this link

Compiled on MacOS HighSierra and getting segmentation fault:

g++ -std=c++11 -I/Library/Frameworks/Python.framework/Versions/2.7/Headers -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"foo.d" -MT"foo.o" -o "foo.o" foo.cpp

g++ -L/usr/local/lib -L/Library/Frameworks/Python.framework/Versions/2.7/ -shared -o foo.so  ./foo.o   -lboost_python27 -lPython

$ python
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 12:01:12) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> dir(foo)
['__doc__', '__file__', '__name__', '__package__', 'cpp_method']
>>> def py_method(**kwargs):
...     print 'from py_method'
...     print kwargs
... 
>>> kwargs = {'arg1': 1, 'arg2': 2}
>>> foo.cpp_method(py_method, kwargs)
Segmentation fault: 11
Process:               Python [22790]
Path:                  /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
Identifier:            Python
Version:               2.7.14 (2.7.14)
Code Type:             X86-64 (Native)
Parent Process:        bash [368]
Responsible:           Python [22790]
User ID:               501

Date/Time:             2018-10-04 16:54:51.618 -0700
OS Version:            Mac OS X 10.13.6 (17G65)
Report Version:        12
Anonymous UUID:        3A7BC812-2E65-69A4-936B-21E5CE648BCF

Sleep/Wake UUID:       E32B82BD-2B4C-4220-A9C2-F71FF57DDA56

Time Awake Since Boot: 580000 seconds
Time Since Wake:       2700 seconds

System Integrity Protection: disabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000048
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x48:
--> 
    __TEXT                 0000000100000000-0000000100001000 [    4K] r-x/rwx SM=COW  /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   org.python.python               0x00007fff3bfaec5c PyErr_Occurred + 14
1   org.python.python               0x00007fff3bf2bdf5 PyObject_IsInstance + 401
2   foo.so                          0x0000000100799aaf boost::python::converter::pyobject_type::check(_object*) + 31 (pyobject_type.hpp:24)
3   foo.so                          0x0000000100799918 boost::python::converter::object_manager_value_arg_from_python::convertible() const + 24 (obj_mgr_arg_from_python.hpp:69)
4   foo.so                          0x00000001007997e1 boost::python::detail::caller_arity::impl >::operator()(_object*, _object*) + 129 (local.hpp:37)
5   foo.so                          0x00000001007996e4 boost::python::objects::caller_py_function_impl > >::operator()(_object*, _object*) + 52 (py_function.hpp:38)
6   libboost_python27.dylib         0x000000010190e1a4 boost::python::objects::function::call(_object*, _object*) const + 820
7   libboost_python27.dylib         0x0000000101910d5a boost::detail::function::void_function_ref_invoker0::invoke(boost::detail::function::function_buffer&) + 26
8   libboost_python27.dylib         0x0000000101916f48 boost::python::handle_exception_impl(boost::function0) + 72
9   libboost_python27.dylib         0x0000000101910871 boost::python::objects::function_call(_object*, _object*, _object*) + 81
10  org.python.python               0x000000010000c2e2 PyObject_Call + 98
11  org.python.python               0x00000001000c30b1 PyEval_EvalFrameEx + 15777
12  org.python.python               0x00000001000cac23 PyEval_EvalCodeEx + 2115
13  org.python.python               0x00000001000cad46 PyEval_EvalCode + 54
14  org.python.python               0x00000001000ef7ec PyRun_InteractiveOneFlags + 380
15  org.python.python               0x00000001000efa4e PyRun_InteractiveLoopFlags + 78
16  org.python.python               0x00000001000f0261 PyRun_AnyFileExFlags + 161
17  org.python.python               0x00000001001071dd Py_Main + 3101
18  org.python.python               0x0000000100000f14 0x100000000 + 3860

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x0000000000000002  rcx: 0x0000000000000001  rdx: 0x0000000000000003
  rdi: 0x00007fff8cc80458  rsi: 0x00000001007b4030  rbp: 0x00007ffeefbff210  rsp: 0x00007ffeefbff210
   r8: 0x00000001007b4030   r9: 0x8c8bb1dcac69804a  r10: 0x0000000000001002  r11: 0xffff8001c47c5769
  r12: 0x0000000000000000  r13: 0x0000000100702a70  r14: 0x0000000100728280  r15: 0x00007fff8cc784f0
  rip: 0x00007fff3bfaec5c  rfl: 0x0000000000010246  cr2: 0x0000000000000048

Logical CPU:     3
Error Code:      0x00000004
Trap Number:     14


Binary Images:
       0x100000000 -        0x100000fff +org.python.python (2.7.14 - 2.7.14)  /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
       0x100003000 -        0x100177fef +org.python.python (2.7.14, [c] 2001-2017 Python Software Foundation. - 2.7.14)  /Library/Frameworks/Python.framework/Versions/2.7/Python
       0x1002ec000 -        0x1002eeff7 +_locale.so (???)  /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_locale.so
       0x1002f2000 -        0x1002f4ff7 +readline.so (???)  /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/readline.so
       0x100730000 -        0x100784fe7 +libncursesw.5.dylib (5)  /Library/Frameworks/Python.framework/Versions/2.7/lib/libncursesw.5.dylib
       0x100795000 -        0x10079bfff +foo.so (0)  /Users/USER/*/foo.so
       0x101900000 -        0x10192dfff +libboost_python27.dylib (0)  /usr/local/opt/boost-python/lib/libboost_python27.dylib
       0x10c12a000 -        0x10c174acf  dyld (551.4)  /usr/lib/dyld
    0x7fff31701000 -     0x7fff31ba2fef  com.apple.CoreFoundation (6.9 - 1454.90)  /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
    0x7fff3bf21000 -     0x7fff3c010ff7  org.python.python (2.7.10 - 2.7.10)  /System/Library/Frameworks/Python.framework/Versions/2.7/Python
    0x7fff56da2000 -     0x7fff56dd5ff7  libclosured.dylib (551.4)  /usr/lib/closure/libclosured.dylib
    0x7fff56f66000 -     0x7fff56f67ff3  libDiagnosticMessagesClient.dylib (104)  /usr/lib/libDiagnosticMessagesClient.dylib
    0x7fff572dc000 -     0x7fff572ddffb  libSystem.B.dylib (1252.50.4)  /usr/lib/libSystem.B.dylib
    0x7fff57511000 -     0x7fff57567fff  libc++.1.dylib (400.9)  /usr/lib/libc++.1.dylib
    0x7fff57568000 -     0x7fff5758cff7  libc++abi.dylib (400.8.2)  /usr/lib/libc++abi.dylib
    0x7fff57ec3000 -     0x7fff57ee1ff7  libedit.3.dylib (50)  /usr/lib/libedit.3.dylib
    0x7fff5803c000 -     0x7fff58263ffb  libicucore.A.dylib (59180.0.1)  /usr/lib/libicucore.A.dylib
    0x7fff585c0000 -     0x7fff585f0ffb  libncurses.5.4.dylib (53)  /usr/lib/libncurses.5.4.dylib
    0x7fff58995000 -     0x7fff58d837e7  libobjc.A.dylib (723)  /usr/lib/libobjc.A.dylib
    0x7fff593ab000 -     0x7fff593bdffb  libz.1.dylib (70)  /usr/lib/libz.1.dylib
    0x7fff59459000 -     0x7fff5945dff7  libcache.dylib (80)  /usr/lib/system/libcache.dylib
    0x7fff5945e000 -     0x7fff59468ff3  libcommonCrypto.dylib (60118.50.1)  /usr/lib/system/libcommonCrypto.dylib
    0x7fff59469000 -     0x7fff59470fff  libcompiler_rt.dylib (62)  /usr/lib/system/libcompiler_rt.dylib
    0x7fff59471000 -     0x7fff5947affb  libcopyfile.dylib (146.50.5)  /usr/lib/system/libcopyfile.dylib
    0x7fff5947b000 -     0x7fff59500fff  libcorecrypto.dylib (562.70.1)  /usr/lib/system/libcorecrypto.dylib
    0x7fff59588000 -     0x7fff595c1ff7  libdispatch.dylib (913.60.2)  /usr/lib/system/libdispatch.dylib
    0x7fff595c2000 -     0x7fff595dfff7  libdyld.dylib (551.4)  /usr/lib/system/libdyld.dylib
    0x7fff595e0000 -     0x7fff595e0ffb  libkeymgr.dylib (28)  /usr/lib/system/libkeymgr.dylib
    0x7fff595ee000 -     0x7fff595eeff7  liblaunch.dylib (1205.70.9)  /usr/lib/system/liblaunch.dylib
    0x7fff595ef000 -     0x7fff595f3ffb  libmacho.dylib (906)  /usr/lib/system/libmacho.dylib
    0x7fff595f4000 -     0x7fff595f6ff3  libquarantine.dylib (86)  /usr/lib/system/libquarantine.dylib
    0x7fff595f7000 -     0x7fff595f8ff3  libremovefile.dylib (45)  /usr/lib/system/libremovefile.dylib
    0x7fff595f9000 -     0x7fff59610fff  libsystem_asl.dylib (356.70.1)  /usr/lib/system/libsystem_asl.dylib
    0x7fff59611000 -     0x7fff59611fff  libsystem_blocks.dylib (67)  /usr/lib/system/libsystem_blocks.dylib
    0x7fff59612000 -     0x7fff5969bff7  libsystem_c.dylib (1244.50.9)  /usr/lib/system/libsystem_c.dylib
    0x7fff5969c000 -     0x7fff5969fffb  libsystem_configuration.dylib (963.50.8)  /usr/lib/system/libsystem_configuration.dylib
    0x7fff596a0000 -     0x7fff596a3ffb  libsystem_coreservices.dylib (51)  /usr/lib/system/libsystem_coreservices.dylib
    0x7fff596a4000 -     0x7fff596a5fff  libsystem_darwin.dylib (1244.50.9)  /usr/lib/system/libsystem_darwin.dylib
    0x7fff596a6000 -     0x7fff596acff7  libsystem_dnssd.dylib (878.70.2)  /usr/lib/system/libsystem_dnssd.dylib
    0x7fff596ad000 -     0x7fff596f6ff7  libsystem_info.dylib (517.30.1)  /usr/lib/system/libsystem_info.dylib
    0x7fff596f7000 -     0x7fff5971dff7  libsystem_kernel.dylib (4570.71.2)  /usr/lib/system/libsystem_kernel.dylib
    0x7fff5971e000 -     0x7fff59769fcb  libsystem_m.dylib (3147.50.1)  /usr/lib/system/libsystem_m.dylib
    0x7fff5976a000 -     0x7fff59789fff  libsystem_malloc.dylib (140.50.6)  /usr/lib/system/libsystem_malloc.dylib
    0x7fff5978a000 -     0x7fff598baff7  libsystem_network.dylib (1229.70.2)  /usr/lib/system/libsystem_network.dylib
    0x7fff598bb000 -     0x7fff598c5ffb  libsystem_networkextension.dylib (767.70.1)  /usr/lib/system/libsystem_networkextension.dylib
    0x7fff598c6000 -     0x7fff598cfff3  libsystem_notify.dylib (172)  /usr/lib/system/libsystem_notify.dylib
    0x7fff598d0000 -     0x7fff598d7ff7  libsystem_platform.dylib (161.50.1)  /usr/lib/system/libsystem_platform.dylib
    0x7fff598d8000 -     0x7fff598e3fff  libsystem_pthread.dylib (301.50.1)  /usr/lib/system/libsystem_pthread.dylib
    0x7fff598e4000 -     0x7fff598e7fff  libsystem_sandbox.dylib (765.70.1)  /usr/lib/system/libsystem_sandbox.dylib
    0x7fff598e8000 -     0x7fff598e9ff3  libsystem_secinit.dylib (30)  /usr/lib/system/libsystem_secinit.dylib
    0x7fff598ea000 -     0x7fff598f1ff7  libsystem_symptoms.dylib (820.60.2)  /usr/lib/system/libsystem_symptoms.dylib
    0x7fff598f2000 -     0x7fff59905fff  libsystem_trace.dylib (829.70.1)  /usr/lib/system/libsystem_trace.dylib
    0x7fff59907000 -     0x7fff5990cff7  libunwind.dylib (35.3)  /usr/lib/system/libunwind.dylib
    0x7fff5990d000 -     0x7fff5993aff7  libxpc.dylib (1205.70.9)  /usr/lib/system/libxpc.dylib

External Modification Summary:
  Calls made by other processes targeting this process:
    task_for_pid: 0
    thread_create: 0
    thread_set_state: 0
  Calls made by this process:
    task_for_pid: 0
    thread_create: 0
    thread_set_state: 0
  Calls made by all processes on this machine:
    task_for_pid: 577992
    thread_create: 0
    thread_set_state: 0

VM Region Summary:
ReadOnly portion of Libraries: Total=213.0M resident=0K(0%) swapped_out_or_unallocated=213.0M(100%)
Writable regions: Total=38.3M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=38.3M(100%)

                                VIRTUAL   REGION 
REGION TYPE                        SIZE    COUNT (non-coalesced) 
===========                     =======  ======= 
Activity Tracing                   256K        2 
Kernel Alloc Once                    8K        2 
MALLOC                            29.5M       12 
MALLOC guard page                   16K        5 
STACK GUARD                       56.0M        2 
Stack                             8192K        2 
VM_ALLOCATE                        256K        2 
__DATA                            4532K       57 
__LINKEDIT                       193.6M       10 
__TEXT                            19.4M       55 
__UNICODE                          560K        2 
shared memory                       12K        4 
===========                     =======  ======= 
TOTAL                            312.0M      143 

Model: MacBookPro12,1, BootROM MBP121.0177.B00, 2 processors, Intel Core i7, 3.1 GHz, 16 GB, SMC 2.28f7
Graphics: Intel Iris Graphics 6100, Intel Iris Graphics 6100, Built-In
Memory Module: BANK 0/DIMM0, 8 GB, DDR3, 1867 MHz, 0x02FE, 0x4544464232333241314D412D4A442D460000
Memory Module: BANK 1/DIMM0, 8 GB, DDR3, 1867 MHz, 0x02FE, 0x4544464232333241314D412D4A442D460000
AirPort: spairport_wireless_card_type_airport_extreme (0x14E4, 0x133), Broadcom BCM43xx 1.0 (7.77.37.31.1a9)
Bluetooth: Version 6.0.7f10, 3 services, 27 devices, 1 incoming serial ports
Network Service: Wi-Fi, AirPort, en0
Serial ATA Device: APPLE SSD SM0512G, 500.28 GB
USB Device: USB 3.0 Bus
USB Device: Bluetooth USB Host Controller
Thunderbolt Bus: MacBook Pro, Apple Inc., 27.1
python
c++
boost-python
pybind11
asked on Stack Overflow Oct 1, 2018 by user3713719 • edited Oct 14, 2018 by user3713719

1 Answer

0

I solved it with pybind11, much easier than boost-python

cpp.cpp:

#include <pybind11/pybind11.h>
#include <iostream>

namespace py = pybind11;

void cpp_method(py::object method, py::kwargs kw) {
    py::object obj = method(**kw);
    std::cout << "Printing from cpp: " << std::string(py::str(obj)) << std::endl;
}

PYBIND11_MODULE(cpp, mod) {
    mod.def("cpp_method", &cpp_method);
}

compilation:

c++ -O3 -Wall -shared -std=c++11 -fPIC `python -m pybind11 --includes` cpp.cpp -o cpp.so `python-config --ldflags`

python:

$ python
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 12:01:12) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cpp
>>> dir(cpp)
['__doc__', '__file__', '__name__', '__package__', 'cpp_method']
>>> def py_method(**kwargs):
...     print 'Printing from python, kwargs: ', kwargs
...     return 'py_method return string'
... 
>>> cpp.cpp_method(py_method, a=1, b=2, c=3)
Printing from python, kwargs:  {'a': 1, 'c': 3, 'b': 2}
Printing from cpp: py_method return string
answered on Stack Overflow Oct 14, 2018 by user3713719

User contributions licensed under CC BY-SA 3.0