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

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

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

37 ответов

19 просмотров

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

сишное 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);...

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

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта