2016-03-12 1 views
1

LibClang предоставляет функцию «определять набор методов, которые переопределяются данным методом» (пояснил here). Однако эта функция, похоже, не отображается в привязках python. Может кто-нибудь объяснить, как добавить эту функцию в привязки или я просто не нашел ее?LibClang Функция связывания Python «getOverridden»

+0

Я нашел решение сам. Вывешивает его позже дома. – cwde

ответ

0

В общем, добавление методов к 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 

 Смежные вопросы

  • Нет связанных вопросов^_^