首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在ctype的方法映射表中未公开的访问方法

在ctype的方法映射表中未公开的访问方法
EN

Stack Overflow用户
提问于 2014-05-13 02:39:06
回答 1查看 227关注 0票数 0

方法映射表是PyMethodDef结构的数组,

代码语言:javascript
运行
复制
struct PyMethodDef {
   char *ml_name;
   PyCFunction ml_meth;
   int ml_flags;
   char *ml_doc;
};

如果ml_name是在解释器中访问的函数的名称(即gc.collect()),则 ml_meth 是上一节中描述的函数的地址,ml_flags表示使用哪个签名,ml_doc是函数的文档字符串。

现在,假设我想从gcmodule.c gc_list_append中访问它,它不是由gc接口公开的。

我试过以下几种方法:

代码语言:javascript
运行
复制
pythonapi.PyImport_ImportModule("gcmodule")

代码语言:javascript
运行
复制
pythonapi.PyImport_ImportModule(ctypes.c_wchar("gcmodule"))

希望返回的引用可以用于访问未公开的方法,但在这两种情况下,我都会得到错误:

代码语言:javascript
运行
复制
ImportError: No module named 'g'

代码语言:javascript
运行
复制
TypeError: one character unicode string expected

知道如何通过ctype/pythonapi访问未公开的函数或数据结构吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-13 04:25:49

PyImport_ImportModule导入一个由const char *参数命名的模块。它调用PyImport_Import,然后在PY2中调用__builtin__.__import__。如果使用C字符串"gc"调用它,则返回对sys.modules['gc']的引用,否则解释器通过调用initgc创建模块,在_PyImport_Inittab中可以找到该模块。gc模块的init函数调用Py_InitModule4,它循环在GcMethods表上向模块dict添加方法。

在gcmodule.c中标记为static的每个全局定义仅在系统级别的编译单元中可见,即它没有外部链接。通常,扩展模块只导出PyMODINIT_FUNC的名称,但CPython中的几个内置模块也会导出公共API(如PyObject_GC_Track )。

在Windows上,按名称或序号从DLL导出符号需要在.def文件中或用修饰符__declspec(dllexport)声明符号。在CPython中,它通过宏PyAPI_FUNC (pyport.h)、PyAPI_DATAPyMODINIT_FUNC应用。例如,objind.h声明了PyAPI_FUNC(void) PyObject_GC_Track(void *)

声明符号static是命名空间管理。但是,如果您可以以某种方式获得函数的地址,那么当然可以使用ctype函数指针来调用它。找到地址才是问题所在。ctypes使用标准的POSIX dlsymGetProcAddress函数来查找导出的符号,这在这里帮不上忙。您可以访问CPython对象直接或间接引用的函数指针,因为id返回对象基地址。

下面的内容与你的问题没有直接关系,但我把它包括在内是为了大家的兴趣。

在用dlopen加载扩展模块的POSIX系统上,可以指定RTLD_GLOBAL将动态符号合并到全局命名空间中。例如,_ctypes扩展模块是从多个对象文件链接的,需要几个extern符号,例如PyCData_set。您可以调整导入,使PyCData_set可以全局访问(例如,通过ctypes.pythonapi):

代码语言:javascript
运行
复制
>>> import sys, DLFCN
>>> sys.setdlopenflags(DLFCN.RTLD_GLOBAL | DLFCN.RTLD_NOW)
>>> import ctypes
>>> hasattr(ctypes.pythonapi, 'PyCData_set')
True

当然,这在Windows上是行不通的。扩展模块使C可用的正确方法是使用PyCapsule,例如datetime.datetime_CAPI (datetimemodule.c)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23621958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档