【问题标题】:LibClang Python binding function "getOverridden"LibClang Python 绑定函数“getOverridden”
【发布时间】:2016-03-12 19:45:49
【问题描述】:

LibClang 公开了一个函数来“确定被给定方法覆盖的方法集”(解释为here)。然而,这个函数似乎没有在 python 绑定中公开。有人能解释一下如何将此函数添加到绑定中还是我没有找到它?

【问题讨论】:

  • 我自己找到了解决方案。稍后会在家里发布。

标签: python libclang


【解决方案1】:

一般来说,向 libclang 添加方法遵循与库本身相同的基本模式。

  1. 您使用 ctypes 来查找要包装的方法的句柄。
  2. 您指定有关参数和返回类型的额外类型信息。
  3. 您将该 ctypes 函数包装在一个处理任何极端情况/缓存的 python 函数中。

对于简单的情况,您可以使用cymbal,这是一个新的 Python 模块,它来自一些试图回答这个问题的实验。 Cymbal 可让您将方法附加到 libclang 类型和游标上。

但是,clang_getOverriddenCursors 比正常情况稍微复杂一些,因为您需要处理通过调用 clang_disposeOverriddenCursors 返回的内存。

此外,libclang 做了一些魔术,这意味着您从该函数返回的游标并非对所有函数调用都有效(它们省略了指向翻译单元的指针),因此您还需要生成更新的游标(基于翻译单位和地点)。

示例代码:

import clang.cindex
from clang.cindex import *

clang_getOverriddenCursors = clang.cindex.conf.lib.clang_getOverriddenCursors
clang_getOverriddenCursors.restype = None
clang_getOverriddenCursors.argtypes = [Cursor, POINTER(POINTER(Cursor)), POINTER(c_uint)]

clang_disposeOverriddenCursors = clang.cindex.conf.lib.clang_disposeOverriddenCursors
clang_disposeOverriddenCursors.restype = None
clang_disposeOverriddenCursors.argtypes = [ POINTER(Cursor) ]

def get_overriden_cursors(self):
    cursors = POINTER(Cursor)()
    num = c_uint()
    clang_getOverriddenCursors(self, byref(cursors), byref(num))

    updcursors = []
    for i in xrange(int(num.value)):
        c = cursors[i]
        updcursor = Cursor.from_location(self._tu, c.location)
        updcursors.append( updcursor )

    clang_disposeOverriddenCursors(cursors)

    return updcursors

假设你想解析这样的东西:

// sample.cpp
class foo {
public:
    virtual void f();
};

class bar : public foo {
public:
    virtual void f();
};

你可以在树中找到方法

idx = Index.create()
tu = idx.parse('sample.cpp', args = '-x c++'.split())
methods = []
for c in tu.cursor.walk_preorder():
    if c.kind == CursorKind.CXX_METHOD:
        methods.append(c)

然后您可以看到覆盖

def show_method(method):
    return method.semantic_parent.spelling + '::' + method.spelling

for m in methods:
    for override in get_overriden_cursors(m):
        print show_method(m), 'overrides', show_method(override)

对我来说打印:

bar::f overrides foo::f

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 2022-01-16
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多