1

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
6
  • You want bp::object (holding the python function), and bp::dict holding the kwargs. Then use operator() of the bp::object, which has an overload taking args and kwargs. | Also see here Commented Oct 3, 2018 at 13:39
  • Thank you. the compiler doesn't resolve get_python_func_of_wrapped_object(). doesn't seems like a boost-python function. do you know where does it come from? Commented Oct 3, 2018 at 23:57
  • Oh, in the scope of that example, that's just a placeholder for some c++ function that returns a bp::object representing the python function you want to call. In your case you already have that as py_method argument of cpp_method. Commented Oct 4, 2018 at 0:06
  • 1
    Check this out. This just passes the dictionary containing the arguments directly to the c++ function. Making it with real keyword args, like you show in your code shouldn't be much harder -- i'll check it out later. Commented Oct 4, 2018 at 0:25
  • Thank you so much for the link. that's exactly I was looking for. I am getting a segmentation fault. Not enough space to paste the back trace. Commented Oct 4, 2018 at 5:21

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.