Как я могу получить модуль Python и номер строки, который вызвал мою функцию C ++ через Boost :: Python? - PullRequest
2 голосов
/ 17 апреля 2010

У меня есть функция C ++, которая вызывается из многих функций Python через Boost :: Python. Когда функция C ++ обнаруживает неверные аргументы, я хочу написать сообщение журнала и продолжить обработку. В этом сообщении я хотел бы отметить модуль Python и номер строки, которая вызывается в C ++. Как я могу это сделать?

Я могу выдать исключение из C ++, которое переведено в исключение Python, которое я могу перехватить, но оно прерывает функцию C ++, которую я не могу иметь.

Например, допустим, я хочу записать предупреждение, если factorial () получает число меньше единицы. Не обращайте внимания на тот факт, что он может легко справиться с делом (и делает это) - мой босс все равно хочет получить предупреждение. ;)

Этот код может вызываться непосредственно из Python или из других функций C ++, которые вызываются из Python, поэтому сама трассировка стека C ++ не очень полезна.

int factorial(int n) {
    if (n < 1) {
        logMsg("invalid n passed to factorial() at %s, line %d", 
                <python-module>, <python-line-number>);
    }
    return n <= 1 ? 1 : n * factorial(n - 1);
}

Я надеюсь, что библиотека Boost :: Python предоставляет эту возможность из C ++.

1 Ответ

0 голосов
/ 18 апреля 2010

Самое простое, что приходит мне в голову, - обернуть библиотеку c ++ модулем python. и иметь функции python, обертывающие функции c ++. Вы должны обменять имя вашего модуля c на модуль python, чтобы все функции python вызывали модуль python вместо модуля c ++.

mv my_cmodule_name.so -> __my_cmodule_name.so (и также изменить внутри кода его имя)

#my_cmodule_name.py

import my_cmodule_name as cmod
import traceback

def catchBadArgsDecorator(function):
    def _inner(*args,**kwds):
        try:
          return function(*args, **kdws)
        except ValueError:
          _, line, function, _ = traceback.extract_stack()[-1]
         log("Call to %s(%s) from %s@%d failed" % ( function.__name__, str(args), function,line)
    return _inner

# for all your modules functions
myfunction = catchBadArgsDecorator(cmod.myfunction)

Код не проверен и может быть улучшен, но я надеюсь, что вы поняли.

...