When I introduced it with homebrew to try Boost.python, I was a little addicted to it. I'll make a note of it.
Let's call a function that returns the square of c ++ from python.
hello_ext.cpp
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
int square(int a)
{
return a*a;
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("square",square);
}
Makefile for building hello_ext.so.
all: hello_ext.so
CC = g++
FRAMEWORK_PATH=/usr/local/opt/python/Frameworks
INCLUDE_PATH=$(FRAMEWORK_PATH)/Python.framework/Versions/2.7/include/python2.7
hello_ext.o: hello_ext.cpp
$(CC) -Wall -O2 -fPIC -c $< -I$(INCLUDE_PATH)
hello_ext.so: hello_ext.o
$(CC) -shared -o $@ $< -lboost_python -F$(FRAMEWORK_PATH) -framework Python
The caller of python.
hello.py
#!/usr/bin/env python
import hello_ext
print hello_ext.square(2)
Build and execution results.
$ make
g++ -shared -o hello_ext.so -I/usr/local/opt/python/Frameworks/Python.framework/Versions/2.7/include/python2.7 hello_ext.o -lboost_python -F/usr/local/opt/python/Frameworks -framework Python
$ python hello.py
4
Well, the code should be cleaner than the old-fashioned Python extensions.
You should use Objective-C ++ to mix Objective-C, for example because you want to use an existing framework. Create the following as hello_ext.mm.
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#import <Foundation/Foundation.h>
int square(int a)
{
return a*a;
}
void nslog(void)
{
NSLog(@"Hello");
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("square",square);
def("nslog",nslog);
}
The Makefile is below. Add -x objective-c ++ when compiling, and the framework path and framework name when linking.
all: hello_ext.so
CC =clang++
FRAMEWORK_PATH=/usr/local/opt/python/Frameworks
INCLUDE_PATH=$(FRAMEWORK_PATH)/Python.framework/Versions/2.7/include/python2.7
FRAMEWORK_PATH2=/System/Library/Frameworks
STD_CPP_PATH = /usr/include/c++/4.2.1/
FRAMEWORK_OPTIONS=-F$(FRAMEWORK_PATH) -framework Python -F$(FRAMEWORK_PATH2) -framework Foundation
hello_ext.o: hello_ext.mm
$(CC) -x objective-c++ -Wall -O2 -fPIC -c $< -I$(INCLUDE_PATH) -I$(STD_CPP_PATH)
hello_ext.so: hello_ext.o
$(CC) -shared -o $@ $< -lboost_python $(FRAMEWORK_OPTIONS)
.PHONY: clean
clean:
rm *.so *.o
You can call it below.
import hello_ext
hello_ext.nslog()
print hello_ext.square(2)
The execution result is as follows.
2017-04-09 11:45:29.818 Python[7710:333116] Hello
4
First, the Official Tutorial says that you can use bjam. bjam can be installed by installing homebrew boost-build, but I was asked to specify the path such as Jamfile, so I gave up because I did not know where to install with homebrew.
Next, I tried to build with g ++ by learning from my predecessors such as I will briefly introduce the functions of Boost.Python. But when I tried to pass the arguments,
Segmentation fault: 11
But
Fatal Python error: PyEval_SaveThread: NULL tstate
It was terrible to say that.
The latter error message got stuck in the search and StackOverflow article Has arrived.
Mostly this is when you have multiple versions of python mixed together, right? If you look at the dependencies with otool -L or something;)
The comment is exactly bingo. Certainly there was a mix of OS X native paths and homebrew paths.
So I solved it by replacing the framework path with homebrew's instead of OSX native with the -F option.
I arrived at the -F option with man ld. I'm ashamed to say that I don't even understand the -framework option. I didn't study enough, but I managed to get it.
Recommended Posts