2011-08-31 3 views
5

Я хотел бы использовать setjmp и longjmp в C-программе, которая ссылается на библиотеку, которая реализована на C++ (но имеет C API).Использование setjmp и longjmp в C при связывании с библиотеками C++

Код C++ выполняет динамическое выделение памяти, и указатели проходят через API, но пока C-сторона кода управляет этими (непрозрачными) объектами правильно, при использовании longjmp не должно возникать никаких помех, правильно?

Я знаю, что использовать эти функции в коде C++ небезопасно, но должно ли быть безопасным в коде C, связанном с кодом на C++?

ответ

3

Тот факт, что вы вызываете функции C++ из вашего кода C, не делает setjmp и longjmp более опасными, чем они всегда есть.

Важно то, что если ваша библиотека выделяет ресурсы, у вас должен быть код восстановления, чтобы гарантировать, что они будут выпущены надлежащим образом после вызова longjmp. Хотя это, вероятно, легко для ваших собственных распределений, может быть трудно или невозможно для библиотеки C++ в зависимости от того, как структурирован используемый вами интерфейс C.

+0

Ok. Мое мышление заключается в том, что до тех пор, пока те распределения, которые были сделаны в библиотеке C++, могут быть очищены с помощью соответствующих вызовов C-интерфейса, код C++ изолирован от эффектов longjmp, а обработка исключений и longjmp не могут мешать каждому Другие. (Я также являюсь разработчиком библиотеки C++.) –

+0

Если у вас есть обработка исключений в C++-библиотеке, вы должны убедиться, что все заброшенные исключения пойманы внутри библиотеки, вы не хотите, чтобы исключения делали ее из вашего кода на C++ (не уверен, что произойдет, если вы это сделаете, никогда не пробовали это). И для освобождения распределений C++ вам нужно будет выяснить, что нужно освободить от кода C, который берет на себя управление после вызова longjmp. Поскольку у вас есть приложение и библиотека, я не вижу никаких проблем, чтобы сделать эту работу. – Miguel

2

setjmp/longjmp, в общем, не безопасен для использования с C++. Они эффективно реплицируют поведение исключений, но не разворачивают стек правильно (например, они не будут запускать деструкторы для объектов в кадрах стека, которые они принудительно выходят). Если возможно, используйте исключения, если вы их получили.

+0

OP не пытается использовать 'setjmp' /' longjmp' в C++, а скорее C-программу, которая использует некоторый код C++ через интерфейс C (который предположительно маскирует все C++-isms в код, вызываемый как C, и делает это безопасно). –

+2

Даже тогда это зависит. Вероятно, было бы безопасно перейти в ваш собственный код, но использование 'longjmp' для выхода из обратного вызова (например) может привести к хаосу. – duskwuff

+0

Использование 'longjmp' для выхода из обратного вызова (если явно не разрешено делать это) звучит как плохая идея, независимо от языка. Вы тоже должны очистить себя в С. –

1

Ну, правильно и не правильно. longjmp будет вообще не вызывать деструкторы, поэтому использовать его в коде, как следующее:

void f(jmp_buf jb) 
{ 
    some_cpp_object_with_a_nontrivial_destructor x; 
    if (some_condition) longjmp(jb, 2); 
    // some other code 
} 

будет делать всякие плохие вещи случаются. Если вы избежите таких ситуаций, вы должны быть в порядке. (В общем, longjmp не должен перепрыгивать через любые активные стоп-кадры с объектами, имеющими нетривиальные деструкторы.)

+0

Мой код C, поэтому я не могу определить локальные переменные с типом, у которого есть конструктор. Поэтому ваш пример не применим к моему вопросу. –

+0

Вы получаете очень похожий сценарий, если вы вызываете обратный вызов функции C++, а callback вызывает longjmp. – zvrba

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