170 похожих чатов

Как делать сишное апи поверх с++? К примеру, функция возвращает

std::string. Делать strdup? С остальными данными также или есть лучше способы?

37 ответов

3 просмотра

Это слишком общий вопрос, делать надо по разному.

сишное api обычно не через strdup возвращает строки, а через параметры

Что касается плюсовых контейнеров, то да, придётся данные копировать в примитивные типы или в какие-то POD-структурки: std::string -> char* std::list -> LIST_HEADER + LIST_ENTRY (Windows only) Ну и так далее, надо просто найти/создать подходящие по смыслу обёрточки Если же это класс с реализацией, то можно в принципе создать экземпляр, а вернуть void*, который потом в приложении скастить к нужному типу (например, если из DLL надо получить что-то)

Georgy Firsov
Что касается плюсовых контейнеров, то да, придётся...

Зачем POD-ы. Я вообще вон писал код из серии типа MyLibInstance* CreateMyLibInstance(...); Ну и потом вызывал методы как-то через someMethod(mylibInstance, ...); что семантически было идентично mylibinstance->someMethod(...);

Alexander N
Зачем POD-ы. Я вообще вон писал код из серии типа ...

+ В Си вполне можно эмулировать ООП и даже полиморфизм с помощью структуры с полями и указателями на "методы". Только вот инициализацию и очистку придется делать ручками.

Dmitriy [Отпуск]
+ В Си вполне можно эмулировать ООП и даже полимор...

Можно, только я видел насколько много макросов для этого приходится городить

Denis Pr
Дак а как строку вернуть из someMethod?

Просто берёшь и возвращаешь. RVO справится.

std::slavik
_Generic

Это не то. Это, скорее, в тему перегрузки.

Flower Surgeon
Это не то. Это, скорее, в тему перегрузки.

нет, женерик это как раз про шаблоны)

Flower Surgeon
Просто берёшь и возвращаешь. RVO справится.

Если имеется ввиду просто вернуть std::string, то это не прокатит

Denis Pr
Если имеется ввиду просто вернуть std::string, то ...

Скорее всего си-апи не просто так нужен. Скорее всего вызывающий код не сможет правильно сделать деаллокейт строке, и будет беда

Flower Surgeon
Почему? https://godbolt.org/z/19zdjd

Я так понимаю изначальный вопрос был «как мне завернуть С++ код в сишный» Я думаю это нужно для того, чтобы сделать шаред либу. Скорее всего это нужно чтобы юзать её из любого другого кода. Например с другим си-рантаймом А если это так, и вы вернёте объект из одного модуля (у которого си-рантайм один) И попытаетесь освободить память в другом модуле (с другим си-рантаймом) — то словите хип-карраптед

Egor-Pugin Автор вопроса
Denis Pr
Я так понимаю изначальный вопрос был «как мне заве...

Обычно в DLL(или .SO) юзают паттерн "фабрика" для вытаскивания интерфейсов. Гляньте в тот же COM от Microsoft.

Egor-Pugin Автор вопроса
Egor Pugin
для этого есть mylib_free()

Дак если либа вернёт объект строки. память на строку удалится на деструкторе строки. А выделялась в другом модуле

Egor-Pugin Автор вопроса
Georgy Firsov
Что касается плюсовых контейнеров, то да, придётся...

сложные данные через опакуе, самое собой

Denis Pr
Дак если либа вернёт объект строки. память на стро...

Возвращай структуры с полями char* str, size, capacity...

Denis Pr
Дак если либа вернёт объект строки. память на стро...

Вроде бы эту проблему должен решить polymorphic allocator, но это не точно.

Egor Pugin
1) пример, 2) какая разница?

Без UB сложно сделать, но чаще всего так поступаю: int len = myfunc(NULL); str.resize(len); myfunc(&str[0]);

Flower Surgeon
Вроде бы эту проблему должен решить polymorphic al...

Не знаю, может быть 🙂 Тут главное понимать что если в каком-то модуле выделилась память — то в том же модуле должна и освободиться. Не знаю как polymorphic allocator эту проблему решит, но может как-то решит )

Denis Pr
Не знаю, может быть 🙂 Тут главное понимать что есл...

Я в своих проектах не перекладываю ответственность на PMR, а просто прибегаю к принципу "я тебя породил — я тебя и убью".

Egor Pugin
что это?

Что это что?

Flower Surgeon
Я в своих проектах не перекладываю ответственность...

Ну дак тогда и из либы не получится вернуть std::string. Разве нет?

Denis Pr
Дак а как строку вернуть из someMethod?

.data()? И дальше что хочешь делай. Хочешь копируй хочешь просто используй не изменяя конечно. Ну это так

Egor Pugin
1) пример, 2) какая разница?

1) errcode_t get_str(char* buf, size_t* buf_size); 2) Ты даёшь клиенту возможность самому управлять памятью

Kirill Bolshakov
1) errcode_t get_str(char* buf, size_t* buf_size);...

Если buf == NULL, то функция в buf_size возвращает размер, который нужен, чтобы поместить строку (если это возможно) + доп. проверки, если переданный buf_size < необходимого. Так обычно сишное апи делает

Kirill Bolshakov
1) errcode_t get_str(char* buf, size_t* buf_size);...

а если рассчитывать размер буфера заранее очень накладно, что тогда? я так понял функция может вернуть необходимое количество памяти для размещения строки

Похожие вопросы

Обсуждают сегодня

Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
55
подскажите пожалуйста, как мне освободить результат записанный в переменную result? в чем проблема подскажите если МОЖЕТЕ?
Михаил Helper
28
есть тут кто-то , кто только начал изучать си? если проходите курс на степике или как-то сами изучаете, пишите, может, скооперируемся?..
Eule
25
Слушайте, ещё такая интересная задачка. Сделан аудит действий пользователей через триггеры в базе, соответственно каждый пользователь имеет свой логин и пароль в базе. Это пре...
Сергей Бычков
12
Скажите, тут нет проблемы? IMyInterface1 = interface function GetInterface2: IInterface2; ... function TMyInterface.GetInterface2: IInterface2; begin Result := TI...
Ruslan aka DUDE
18
вопрос по москвину - не понимаю вот такого вопроса похоже Сколько разных всегда завершающихся функций с типом a -> a -> b -> a -> a можно реализовать? Две функции одинаково...
Fedor
11
Кстати, раз про скачивание файлов разговор зашел) Сделал бота для себя (транскрибирующего и суммаризирующего встречи) но не ожидал что за 2 месяца 10к пользователей набежит😅...
Andrey Obolenskiy
8
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
Утра доброго. Просветите пожалуйста. Хочу сделать rest сервер на делфи. Посмотрел 3 фреймворка: dmvc, Mars, mormot. Ни в одном из них не упоминается ассинхронная обработка вхо...
Сергей Бычков
10
возможно для форматирования TimeStampZ нужен другой механизм, не?
Роман Лях (rgreat)
13
Карта сайта