Переопределить код C, чтобы вызвать исключение C ++? - PullRequest
1 голос
/ 25 октября 2019

У меня есть библиотека C (вызываемая из кода C и C ++), которая обрабатывает недопустимый ввод путем простого выхода. Выглядит это так

#ifdef __cplusplus
extern "C" {
#endif

void exitWithError(const char* func) {
    printf("woopsie in %s", func);
    exit(1);
}

void myfunc(int i) {
    if (i < 0)
        exitWithError(__func__);
}

#ifdef __cplusplus
}
#endif

Эта библиотека скомпилирована в «режиме C», даже если она связана с кодом C ++. Т.е. используя

g++ -x c <abovelibrary.c>

Я использую эту библиотеку в коде C ++ и хочу, чтобы она вызвала исключение вместо выхода. Например,

void exitWithError(const char* func) {
    throw std::invalid_argument( func );
}

Можно ли использовать директивы препроцессора для переопределения exitWithError в C ++, чтобы он генерировал исключение для кода внешнего вызывающего C ++, но все еще был совместим с внутренним кодом вызывающего C?

Можно ли это сделать дальше без изменения исходной библиотеки C (хотя это не является строгим требованием)?

Для контекста я использую библиотеку C ++ Catch2 для модульного тестирования лежащего в основеC и желаем проверить, правильно ли обрабатываются недействительные пользовательские вводы (используя макрос REQUIRE_THROWS Catch2). Я использую C ++ 14, если это имеет значение, и библиотека C соответствует C99.

1 Ответ

0 голосов
/ 15 ноября 2019

Согласно этому вопросу , мы можем объявить exitWithError как слабый символ из библиотеки C

#pragma weak exitWithError
void exitWithError(const char* func) {
    printf("woopsie in %s", func);
    exit(1);
}

и переопределить его в C ++,выдает исключение.

extern "C" void exitWithError(const char* func) {
    throw std::invalid_argument(func);
}

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

...