如何使用正确的本机调用约定编译C扩展?

阿维夫·科恩(Aviv Cohn)

假设我们正在用C编写一个CPython扩展模块。

定义扩展名时,我们需要提供PyMODINIT_FUNC PyInit_<module_name>(void)在此声明中没有指定本地调用约定。

无论是在Linux上还是在Windows上,扩展开发人员如何才能确保PyInit_使用正确的调用约定来编译函数,以便解释器在运行时成功调用函数?Python标头中是否有一些魔术可以帮助我们解决此问题?或者是其他东西?

相同的问题适用于扩展模块中包含的本机函数,并暴露给包装为函数对象的Python。我们如何确保以与Python解释器调用约定兼容的方式进行编译?

安蒂·哈帕拉(Antti Haapala)

你是在写作PyMODINIT_FUNC PyInit_<module_name>(void)现在PyMODINIT_FUNC是一个宏,它扩展为由#ifdefin中的各种s控制的不同事物pyport.h在当前的HEAD版本中,Github版本Python 3.9开发版本具有以下6个定义:

#define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
#define PyMODINIT_FUNC PyObject*
#define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
#define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
#define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
#define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*

即,它可以扩展PyObject *为返回类型,但也extern "C"可以使用C ++编译器进行编译以确保针对该符号进行C链接,并且Py_EXPORTED_SYMBOL在某些平台上也包含

Py_EXPORTED_SYMBOL被定义exports.h

#define Py_EXPORTED_SYMBOL __declspec(dllexport)
#define Py_EXPORTED_SYMBOL __attribute__ ((visibility ("default")))
#define Py_EXPORTED_SYMBOL

这些都没有指定调用约定,而是让函数默认使用cdecl约定...-还应注意,调用约定大部分仅在Windows中才有用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

默认情况下,是否使用cdecl + fastcall约定编译c ++成员函数?

如何使用TCL绑定编译SQLite?

使用GMP设置Netbeans,如何指定编译选项?

为什么go的编译器“ gc”使用与C不同的调用约定?

如何正确使用“扩展”?

如何确定编译的哪个阶段?

C ++未知调用约定

如何正确调用 WCF ServiceClient 代理扩展?

如何使用Java调用调用本机C ++库的C#库

此Makefile如何使C程序甚至不指定编译器?

如何正确使用jQuery扩展

Sublime Text:如何自动使用某些文件扩展名的特定编码打开?

在C / C ++中通过指针调用函数时,编译器如何正确处理ABI?

如何从反应本机代码调用C函数?

如何确定编译给定代码所需的编译标志?

如何将Java空参数传递给使用JNA编译为C代码的本机方法?

如何使用C函数调用促进OCamljava编译ocaml库?

如何知道Qt项目是否正在使用调用约定?

Objective-C中类扩展的正确文件命名约定是什么?

编译通过Windows MS / VS上的node-gyp使用调用约定的代码

如何为Python编译C扩展

如何使用扩展的图像支持编译pygame?

何时使用`__fastcall`调用约定

c# - 如何设置使用反射调用的参数的正确顺序?

带有pascal调用约定的Pinvoke本机方法

在C / C ++中确定编译时的内核数

内联扩展编译为函数调用 [c++]

在引导加载程序中使用的正确调用约定是什么?

如何使用Visual Studio 2017调试来自asp.net的本机C ++调用