Передача std::string в API библиотеки

В настоящее время мы создаем API для определенной библиотеки. Часть интерфейса требует, чтобы библиотека получала и возвращала пользовательские классы, такие как вектор и строка.

При попытке смоделировать использование библиотеки в простом сценарии в режиме отладки система зависает при доставке строки в качестве входных данных.

Я считаю, что существует другое представление класса строки в режиме отладки или выпуска. Тогда наша библиотека предполагает получить некое представление, неправильно прочитать элемент данных и раздавить по пути. Итак, каков наилучший способ передачи объектов STL в API. Целевая ОС — Windows XP, скомпилированная с MSVC 8, хотя пользователь библиотеки будет использовать Windows, их компилятор может (и, вероятно, будет) отличаться. Идеи, которые у нас были до сих пор:

  1. Измените строку на char*. Но тогда разработчики могут быть сбиты с толку ответственностью за освобождение памяти.
  2. Используйте нашу собственную версию String — я не хочу разрабатывать еще одну частную реализацию строки.
  3. Выпуск пользовательской отладочной версии и выпускной версии.
  4. Спросите у людей в Stack Overflow какой-нибудь вариант, который мы пропустили или не поняли, или просто узнали из их опыта — готово.

person Hagai    schedule 02.07.2010    source источник
comment
Верите ли вы, что существует другое представление, или вы знаете, что оно существует?   -  person    schedule 02.07.2010
comment
@Нил: хорошая мысль. Вы знаете больше об этом? Однако, даже если между выпуском и отладкой нет разницы, использование STL в API, используемом третьими сторонами, ИМХО, все еще сомнительно.   -  person lornova    schedule 02.07.2010
comment
И если ваша библиотека получит объект, который будет содержать данные, которые необходимо доставить. Таким образом, нет риска высвобождения данных памяти.   -  person lsalamon    schedule 02.07.2010
comment
@Нил: я верю. Потому что, если конфигурация пользовательского имитирующего кода находится в выпуске, все работает просто отлично. Если вы вычислите sizeof(String) в выпуске и в конфигурации отладки, вы получите разные результаты.   -  person Hagai    schedule 02.07.2010
comment
Вы прямо не говорите, какую ОС и набор инструментов вы используете. Все догадываются, что это Windows + VisualC++. Вероятно, это связано с тем, что Windows имеет странную семантику управления памятью, когда вы начинаете использовать библиотеки DLL, а также делает отладочные и выпускные двоичные файлы, которые не совместимы по ссылке. У Unix обычно нет таких проблем — конечно, я написал множество библиотек, которые использовали типы STL в API, и у меня никогда не было проблем. Итак, возможно, вам следует просто уточнить, какая у вас целевая платформа.   -  person alex tingle    schedule 03.07.2010
comment
@alex tingle: Спасибо, я разъяснил проблему в вопросе.   -  person Hagai    schedule 03.07.2010


Ответы (2)


Вам следует избегать передачи объектов STL между разными двоичными модулями.

Для строки вы должны полагаться на const char* для параметра только для чтения и char*, <buffer size> для входных параметров...

Для векторов это может быть немного сложнее, особенно если вам нужно изменить содержимое вектора...

О ваших идеях:

  1. Вы правы, но соглашение обычно заключается в том, что вы не можете сохранить переданный указатель (вы должны сделать свою локальную копию).
  2. В конце у вас будет та же проблема, если у вас нет одинакового двоичного представления в версии отладки и версии вашей реализации.
  3. Это может быть вредно, если вы используете разные версии/реализации STL в двух бинарных модулях (если только вы не уверены, что пользователь библиотеки будет использовать один и тот же STL).
person lornova    schedule 02.07.2010
comment
Для проголосовавших против: пожалуйста, добавьте пояснительный комментарий, чтобы мы могли понять, что не так... - person lornova; 02.07.2010
comment
Пожалуйста, объясните, что вы подразумеваете под бинарными модулями. - person ; 02.07.2010
comment
@Neil: например, .exe и .dll, или статически связанная библиотека, или вообще любые два скомпилированных модуля, которые будут связаны друг с другом. Если они используют разные реализации STL... упс. - person lornova; 02.07.2010
comment
@lorenzo Я постоянно передаю строки, векторы и т. д. в статические библиотеки без проблем. Конечно, библиотеки должны быть скомпилированы тем же компилятором, что и исполняемый файл, но то же самое справедливо и для кода C, если библиотека и исполняемый файл имеют общие обязанности по управлению памятью. - person ; 02.07.2010
comment
@Neil: я думал, что C (не совсем уверенный перед C++) имеет бинарное соответствие (между разными реализациями) на уровне компоновщика, когда используется одно и то же соглашение о вызовах. Вы почти правы в отношении управления памятью: вы не можете free память с библиотекой C, которая была распределена с другой библиотекой C, по этой причине при разработке библиотек используется распределитель операционной системы (по крайней мере, в Windows). - person lornova; 02.07.2010
comment
@Lorenzo Нет, стандарта двоичной совместимости C не существует, хотя на большинстве платформ есть стандарт по умолчанию. И когда я разрабатываю библиотеки, я обычно не рассматриваю платформу и уж точно не вызываю такие вещи, как GlobalAlloc(). - person ; 02.07.2010
comment
Просто чтобы немного расширить точку зрения Лоренцо: вы должны убедиться, что обе используют точно такую ​​​​же отладочную или не отладочную копию DLL среды выполнения C. Если есть несоответствие или они статичны, это не сработает. - person Rup; 02.07.2010
comment
@Neil: хм, ты прав ... совместимость C ABI фактически обеспечивается ABI, используемым системными вызовами на определенных платформах ... - person lornova; 02.07.2010
comment
@Rup: точно, однако, если вы разрабатываете библиотеку, вы не должны заставлять клиента использовать конкретную реализацию STL ... - person lornova; 02.07.2010
comment
@ Лоренцо. На самом деле нет - бинарный ABI навязывается (если это слово) самым популярным компилятором и компоновщиком. Системные вызовы (по крайней мере, в Linux) фактически вызываются программным прерыванием. - person ; 02.07.2010
comment
@Neil: я не имею дело с ОС шестидесятых :-) Кроме шуток, в Windows системные вызовы являются функциями C, поэтому соглашение о вызовах, использующее там, является де-факто стандартным ABI (вы можете утверждать, что фактический системный вызов выполняется с системным вызовом ASM даже в Windows, но разработчик не должен этим заниматься). - person lornova; 02.07.2010
comment
@lorenzo UNIX — это ОС из 70-х, Windows — это ОС из 80-х, а Linux — это ОС из 90-х. Кроме того, Windows на самом деле не документирует, что является и не является системным вызовом, который обычно считается переключением в режим ядра. Конечно, все это не имеет ничего общего с C ABI. - person ; 02.07.2010
comment
@lorenzo Если вы предоставляете двоичную библиотеку, вы должны заставить библиотеку использовать ту же (а не конкретную) реализацию стандартной библиотеки, что и вызывающая сторона. - person ; 02.07.2010
comment
@Neil: UNIX из 1969 года, а Linux настолько похож на UNIX, что его нельзя считать дизайном 90-х. Однако это явно была шутка. - person lornova; 02.07.2010
comment
@Neil: задокументированный способ вызова системных служб Windows — использовать Windows API, который представляет собой набор функций C. Соглашение о вызовах этих функций C, а также требования к выравниванию де-факто являются стандартом C ABI в Windows. - person lornova; 02.07.2010

Совершенно неразумно заставлять людей ссылаться на отладку в режиме отладки и выпускать в режиме выпуска. Так поступает практически каждая библиотека. Даже такие крупные проекты, как DirectX, выпускают отладочные компиляции своих двоичных файлов. №3 — вполне разумный вариант/решение.

person Puppy    schedule 02.07.2010
comment
@Lorenzo: вы используете STL своего компилятора. Если у вас есть бесплатный компилятор, такой как GCC, вы заставляете своих пользователей обновлять его. Если у вас есть платный, более версионный компилятор, такой как MSVC, вы просто компилируете его с помощью MSVC8,9,10. - person Puppy; 02.07.2010
comment
@DeadMG: но если вы скомпилируете свою библиотеку с помощью данного компилятора, если вы экспортируете объекты STL, вы заставите пользователя библиотеки использовать ту же среду в своем приложении. - person lornova; 03.07.2010
comment
@Lorenzo: в любом случае библиотеки несовместимы между процессорами и т. д. Если у вас есть одна и та же цель, вполне разумно использовать один и тот же компилятор. - person Puppy; 03.07.2010
comment
@DeadMG: Итак, я поставщик библиотеки (предположим, Windows и DLL) и предпочитаю использовать компилятор Intel C++ 10 и sgi STL. Заказчик не будет знать, какую библиотеку и компилятор я использую, так как он получит бинарный модуль. Он будет использовать MSVC 7 со стандартным STL. Моя библиотека экспортирует строки и векторы STL, совместимы ли две реализации? - person lornova; 03.07.2010
comment
@Lorenzo: Вот почему вы используете компилятор большинства для своей платформы. MSVC Express бесплатен. - person Puppy; 03.07.2010