Какая из них лучше — вызывать библиотеку c ++ из программы c?

У меня есть библиотека C ++ .so. Мой сотрудник работает над программой на c, которая будет вызывать библиотеку c ++ из своей программы на c. Я сказал ему, чтобы он создал Wrapper.h и Wrapper.cpp и использовал указатель для передачи объектов c ++ в своей программе c. Однако я обнаружил, что он пытается изменить исходный код нашей библиотеки c ++, добавив Wrapper.cpp и заголовок в нашу библиотеку .so напрямую. Например:

class A{ SetValueA(int); }
class B{ SetValueB(int); }

В своем Wrapper.cpp он написал так:

A a;
B b;
extern "C" SetValueA(int) {a.SetValueA(int); }
extern "C" SetValueB(int) {b.SetValueB(int); }

Затем он перекомпилировал нашу библиотеку c ++ и включил в свою программу Wrapper.h.

То, что я сказал ему, это сделать так:
В моем Wrapper.cpp

extern "C" {
A* newClassA() {
return new A();
}

void SetValueA(A* v, int i) {
v->SetA(i);
}
B* newClassB() {
return new B();
}

void SetValueB(B* v, int i) {
v->SetB(i);
}

void deleteClassA(A* v) {
delete v;
}
void deleteClassB(B* v) {
delete v;
} }

Затем я просто скомпилировал мой Wrapper.cpp и связал его с нашей библиотекой c ++. В своей программе на c ему просто нужно включить Wrapper.h и скомпилировать его код на c, а затем скомпилировать Wrapper.o и main.o (из main.c) с помощью компилятора c ++.

Его решение тоже работает, он жаловался, что, как я сказал ему, больше работает. Но я не хочу, чтобы он изменил нашу библиотеку c ++, потому что никто другой не будет использовать класс Wrapper из библиотеки c ++. Можете ли вы сказать мне, какой из них лучше и почему?

Да, мне также не нравится, как он использует глобальную переменную в своей оболочке.

2

Решение

Я не понимаю, почему необходимо изменить какой-либо библиотечный файл для использования глобальных переменных: необходимое изменение должно быть ограничено Wrapper.cpp который явно является частью оболочки.

Тем не менее, я не верю в использование какого-либо [изменяемого] глобального объекта. Они имеют тенденцию быть проблемой по-разному. То есть я бы согласился с тем, что правильный подход к созданию обертки — это эффективная работа с необходимым управлением на протяжении всей жизни. Я понимаю, что правильно распределить управление жизненным циклом в C сложнее, чем в C ++. Решением этой проблемы является использование C ++, а не создание ненужных зависимостей (я знаю, что этот аргумент обычно не работает с программистами на C).

3

Другие решения

Оболочка, которую написал ваш коллега, конечно же, неразборчива из-за использования глобальных переменных, которые привносят множество проблем в вашу библиотеку.

Однако я считаю, что хорошо написанная библиотека должна экспортировать интерфейс C самостоятельно, даже если она использует C ++ для внутреннего использования. По той простой причине, что интерфейс C может быть импортирован практически на любой язык, в то время как интерфейс C ++ требует, чтобы пользовательский код был C ++. Кроме того, использование этого вида оболочки в пользовательском коде может привести к распространению различных версий wrapper.cpp, которые по-разному являются неполными и устаревшими.

Таким образом, я бы включил код в соответствии с вашими wrapper.cpp в вашу библиотеку. И я бы, конечно, переместил его ближе к коду, который он упаковывает, вместо того, чтобы связать все это в один большой, толстый wrapper.cpp. Таким образом, гораздо проще проверить, все ли ваши публичные методы были правильно упакованы.

0

По вопросам рекламы [email protected]