Quand je l'ai introduit avec homebrew pour essayer Boost.python, j'en étais un peu accro. Je vais en prendre note.
Appelons une fonction qui renvoie le carré de c ++ à partir de 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 pour construire 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
L'appelant de python.
hello.py
#!/usr/bin/env python
import hello_ext
print hello_ext.square(2)
Résultats de construction et d'exécution.
$ 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
Eh bien, le code doit être plus propre que les extensions Python à l'ancienne.
Vous devez utiliser Objective-C ++ pour mélanger Objective-C car vous souhaitez utiliser un framework existant. Créez ce qui suit en tant que 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);
}
Le Makefile est ci-dessous. Ajoutez -x objective-c ++ lors de la compilation, ainsi que le chemin et le nom du framework lors de la liaison.
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
Vous pouvez l'appeler ci-dessous.
import hello_ext
hello_ext.nslog()
print hello_ext.square(2)
Le résultat de l'exécution est le suivant.
2017-04-09 11:45:29.818 Python[7710:333116] Hello
4
Tout d'abord, le Tutoriel officiel indique que vous pouvez utiliser bjam. Vous pouvez installer bjam en installant boost-build de homebrew, mais on m'a demandé de spécifier le chemin tel que Jamfile, donc j'ai abandonné car je ne savais pas où installer avec homebrew.
Ensuite, j'ai essayé de construire avec g ++ en apprenant de mes prédécesseurs tels que Je vais brièvement présenter les fonctions de Boost.Python. Mais quand j'ai essayé de passer l'argument
Segmentation fault: 11
Mais
Fatal Python error: PyEval_SaveThread: NULL tstate
C'était terrible de dire ça.
Le dernier message d'erreur est resté bloqué dans la recherche et dans article StackOverflow Est arrivé.
C'est surtout lorsque plusieurs versions de python sont mélangées, non? Si vous regardez les dépendances avec otool -L ou quelque chose;)
Le commentaire est exactement le bingo. Il y avait certainement un mélange de chemins natifs OSX et de chemins homebrew.
J'ai donc résolu le problème en remplaçant le chemin du framework par celui de l'homebrew au lieu de celui natif d'OSX avec l'option -F.
Je suis arrivé à l'option -F avec man ld. J'ai honte de dire que je ne comprends même pas l'option -framework. Je n'ai pas assez étudié, mais j'ai réussi à l'obtenir.
Recommended Posts