Когда нужно либу на C++ сделать доступной для нормальных (с человеческим лицом) языков программирования — приходится переходить на extern "C". А значит многих фишек C++ уже не будет.
К примеру, не будет ссылок — а только указатели.
Не будет исключений.
Но то пол беды еще, больше интересует вопрос очистки памяти.
К примеру, некая функция возвращает указатель void*. А внутри там объект класса из C++. Если его получит прога и вызовет calloc.free для этого указателя — вызовется ли деструктор? Нужно ли каждое поле отдельно делать calloc.free ?
Здравствуйте, Shmj, Вы писали:
S>К примеру, некая функция возвращает указатель void*. А внутри там объект класса из C++. Если его получит прога и вызовет calloc.free для этого указателя — вызовется ли деструктор? Нужно ли каждое поле отдельно делать calloc.free ?
Нет, нужно отдельно проэкспортировать функцию, которая умеет иничтожать такие объекты, и пусть она сама зовет delete() на C++-ной стороне.
Не надо освобождать C++-ные объекты с помощью free(). Деструктор никто не позовет и вообще никто не обещал, что это в принципе будет работать.
Здравствуйте, Shmj, Вы писали:
S>К примеру, некая функция возвращает указатель void*. А внутри там объект класса из C++. Если его получит прога и вызовет calloc.free для этого указателя — вызовется ли деструктор? Нужно ли каждое поле отдельно делать calloc.free ?
Здравствуйте, Shmj, Вы писали:
S>Когда нужно либу на C++ сделать доступной для нормальных (с человеческим лицом) языков программирования — приходится переходить на extern "C". А значит многих фишек C++ уже не будет. S>К примеру, не будет ссылок — а только указатели. S>Не будет исключений.
А ламочка Ильича может работать на дровах.
S>Но то пол беды еще, больше интересует вопрос очистки памяти.
Ты в следующий раз начинай сразу с вопроса. Потому что тоннами бреда, который ты генеришь, ты успеваешь отбить всякое желание отвечать тебе.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Ты в следующий раз начинай сразу с вопроса. Потому что тоннами бреда, который ты генеришь, ты успеваешь отбить всякое желание отвечать тебе.
Здравствуйте, Shmj, Вы писали:
S>Когда нужно либу на C++ сделать доступной для нормальных (с человеческим лицом) языков программирования — приходится переходить на extern "C". А значит многих фишек C++ уже не будет. S>К примеру, не будет ссылок — а только указатели. S>Не будет исключений.
Если библиотека имеет plain C интерфейс, это вовсе не означает, что она должна быть полностью написана на чистом С. Внутри ты можешь спокойно использовать все перечисленное и гораздо больше.
S>К примеру, некая функция возвращает указатель void*. А внутри там объект класса из C++. Если его получит прога и вызовет calloc.free для этого указателя — вызовется ли деструктор? Нужно ли каждое поле отдельно делать calloc.free ?
Тебе не обязательно возвращать наружу указатели в чистом виде (хотя и такая возможность тоже есть, конечно же). Наружу ты можешь возвращать какие-то безликие дескрипторы, об устройстве и формате которых знаешь только ты. Например, это может быть указатель, закриптованный каким-то нехитрым способом. Или, например, это может быть целочисленный тип 32 или 64 в котором зашифрован индекс типа и индекс объекта. Или еще что-то. Главное то, что все манипуляции с предоставленным тобой ресурсом, включая его освобождение, пользователь должен выполнять через предоставленные тобой же функции, и не пытаться применть к ним какие-нибудь free или delete.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Shmj, Вы писали:
S>Когда нужно либу на C++ сделать доступной для нормальных (с человеческим лицом) языков программирования — приходится переходить на extern "C". А значит многих фишек C++ уже не будет.
extern "C" означает что имя функции в библиотеке будет сформировано по правилам C. Обычно это добавление префикса "_" к имени. По молчанию, по правилам C++ экспортируемый символ формируется по правилам т.к. "мэнглинга" из сигнатуры функции.
Здравствуйте, Shmj, Вы писали:
S>Когда нужно либу на C++ сделать доступной для нормальных (с человеческим лицом) языков программирования — приходится переходить на extern "C". А значит многих фишек C++ уже не будет.
Нормальных это питон? Ммм... Нормальность которую мы заслужили. S>К примеру, не будет ссылок — а только указатели.
Не проблема. S>Не будет исключений.
Не больно-то и хотелось. S>Но то пол беды еще, больше интересует вопрос очистки памяти.
Да, это проблема. Если у тебя винда, то рекомендую использовать COM. S>К примеру, некая функция возвращает указатель void*. А внутри там объект класса из C++. Если его получит прога и вызовет calloc.free для этого указателя — вызовется ли деструктор? Нужно ли каждое поле отдельно делать calloc.free ?
Проблема ещё глубже, разные приложухи могут использовать разный crt что может, ок, скорее всего приведёт приключениям при отладке. Конечно, можно запускаться с одним, но про это всегда надо помнить.
Здравствуйте, Shmj, Вы писали:
S>Когда нужно либу на C++ сделать доступной для нормальных (с человеческим лицом) языков программирования — приходится переходить на extern "C". А значит многих фишек C++ уже не будет.
Нет, не значит. extern "C" — это всего лишь указание компилятору/библиотекарю/линкеру, чтобы экспортируемым объектам давали простые имена.
Фишки, которые мы здесь потеряли — это одноимённые сущности (прежде всего, перегрузки функций).
S>К примеру, не будет ссылок — а только указатели.
Это в том случае, если "нормальный с человеческим лицом" язык оперирует голыми указателями. Что отнюдь не факт.
S>Не будет исключений.
У "нормального с человеческим лицом" языка программирования может быть свой механизм исключений, не похожий на плюсовый.
И так и этак придётся делать адаптацию.
Например, транслировать питоньи исключения в плюсовые и наоборот, или плюсовые исключения в сишные виндовые структурные, или плюсовые в одном рантайме в плюсовые в другом рантайме.
S>Но то пол беды еще, больше интересует вопрос очистки памяти.
Это четверть и даже осьмушка беды.
В любой библиотеке есть правило: кто память выделил, тот её и освобождает.
И любой адаптер (хоть плюсовый к "нормально-человеческой" — к той же питоньей, хоть "нормально-человеческий" к плюсовой) должен автоматизировать вызовы функций освобождения.
Даже плюсовый к плюсовой такое может делать: shared_ptr с пользовательским делителем deleter'ом.
class Foo {
private:
~Foo();
public:
static std::shared_ptr<Foo> Create(.....);
};
S>К примеру, некая функция возвращает указатель void*. А внутри там объект класса из C++. Если его получит прога и вызовет calloc.free для этого указателя — вызовется ли деструктор? Нужно ли каждое поле отдельно делать calloc.free ?
А к примеру, если тот же фокус проделает плюсовый код с плюсовым объектом?
Мало ли способов выстрелить в ногу.
Разработчики библиотек с сишным интерфейсом стараются принять меры против шаловливых ручек. Отдают не голые void* "реинтерпретируй меня как хочешь", а всякие там HANDLE.
Для которых валидный способ грохнуть — это вызвать DeleteTheObject(HANDLE), а как это внутри устроено — дело библиотечное.
А если "нормальный с человеческим лицом" язык умеет в RAII, то он вызовет делитель хэндла в своей умной человеческой обёртке.
Здравствуйте, Кодт, Вы писали:
S>>Когда нужно либу на C++ сделать доступной для нормальных (с человеческим лицом) языков программирования — приходится переходить на extern "C". А значит многих фишек C++ уже не будет.
К>Нет, не значит. extern "C" — это всего лишь указание компилятору/библиотекарю/линкеру, чтобы экспортируемым объектам давали простые имена. К>Фишки, которые мы здесь потеряли — это одноимённые сущности (прежде всего, перегрузки функций).
Мы тут не только потеряли, но и приобрели. Приобрели веселье, которое начнётся, если в разных местах одноимённые extern "C" сущности будут разных типов
Здравствуйте, Marty, Вы писали:
M>Мы тут не только потеряли, но и приобрели. Приобрели веселье, которое начнётся, если в разных местах одноимённые extern "C" сущности будут разных типов
Для предотвращения таких проблем в C-шниых либах обычно используются всякие суффиксы/префиксы, которые добавляются ко всем публичным именам.
--
Не можешь достичь желаемого — пожелай достигнутого.