如何将C++的API封装成python可调用形式
展开全部
在C++的库上面套一层wrapper就可以了。
可以包装成CPython模块,也可以包装成C库然后用ctypes、cffi调用。
要对付主要是是C++的函数命名和类型。
包装CPython模块可以看手册里「Extending and Embedding」的部分。只要保证initMODULENAME(2.x)或PyInit_MODULENAME(3.x)是extern "C"的就行,手册里的例子用了PyMODINIT_FUNC这个宏,已经自动给加好了。
包装C库就是把所有函数都声明成extern "C"的,把传递的C++类型以C类型替代。举个例子
namespace enemy {
void first_blood(int id);
} // namespace enemy
void double_kill();
void double_kill(int killer);
class Silencer
{
public:
std::string watch_and_learn();
};
包装之后大概是这样的:
extern "C" {
void enemy_first_blood(int id)
{
enemy::first_blood(id);
}
void double_kill_by_roshan()
{
double_kill();
}
void double_kill_by_hero(int killer)
{
double_kill(killer);
}
void* new_silencer()
{
return new Sliencer;
}
void silencer_watch_and_learn(void *instacne, char *buffer)
{
std::string what = reinterpret_cast<Silencer*>(instance)->watch_and_learn();
strcpy(buffer, what.c_str());
}
void release_silencer(void *instacne)
{
delete reinterpret_cast<Silencer*>(instance);
}
} // extern "C"
可以包装成CPython模块,也可以包装成C库然后用ctypes、cffi调用。
要对付主要是是C++的函数命名和类型。
包装CPython模块可以看手册里「Extending and Embedding」的部分。只要保证initMODULENAME(2.x)或PyInit_MODULENAME(3.x)是extern "C"的就行,手册里的例子用了PyMODINIT_FUNC这个宏,已经自动给加好了。
包装C库就是把所有函数都声明成extern "C"的,把传递的C++类型以C类型替代。举个例子
namespace enemy {
void first_blood(int id);
} // namespace enemy
void double_kill();
void double_kill(int killer);
class Silencer
{
public:
std::string watch_and_learn();
};
包装之后大概是这样的:
extern "C" {
void enemy_first_blood(int id)
{
enemy::first_blood(id);
}
void double_kill_by_roshan()
{
double_kill();
}
void double_kill_by_hero(int killer)
{
double_kill(killer);
}
void* new_silencer()
{
return new Sliencer;
}
void silencer_watch_and_learn(void *instacne, char *buffer)
{
std::string what = reinterpret_cast<Silencer*>(instance)->watch_and_learn();
strcpy(buffer, what.c_str());
}
void release_silencer(void *instacne)
{
delete reinterpret_cast<Silencer*>(instance);
}
} // extern "C"
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询