C++: интерфейс dll, lib

Realist

Нубский вопрос, возможно. Вот типа стандарт С++ не гарантирует, какие именно будут размеры типов, выравнивания в структурах и прочее. А я вот пишу библиотеку. Скажем, dll под Win32. Один вариант — распространять dll под каждый компилятор. Второй вариант — в интерфейс высовывать только то, что гарантированно у всех в win32 одинаковое. Внимание, вопросы:
1. Если идти по первому пути, то как именно? Под каждый (популярный) компилятор своя dll? Или под каждый компилятор debug и release dll? Или под каждый компилятор и под каждое сочетание его параметров кодогенерации?
2. Если идти по второму пути, то на что я могу рассчитывать? Скажем, int через интерфейс прокинуть, потому что это win32? А char могу? А указатель на интерфейс (чисто абстрактный класс)? Что еще? Тут интересует, что можно делать по факту (char = 8 bit потому что всегда равно а что по какому стандарту (размер int 32 bit потому что win32)? Почему endian с обоих сторон dll одинаковый?
3. Как решаются вопросы 1 и 2 в никсах? Все компилят gcc -O2?
4. Как оно в жизни-то делается?
Спасибо

Dasar

А я вот пишу библиотеку. Скажем, dll под Win32.
тогда рекомендуется оформлять ее как com-библиотеку, это позволит не только ее вызывать из любого С++-компилятора, но вообще из любого языка (дельфи, .net, java и т.д.)

evolet

2. Если идти по второму пути, то на что я могу рассчитывать? Скажем, int через интерфейс прокинуть, потому что это win32? А char могу?
да да
>А указатель на интерфейс (чисто абстрактный класс)?
нет, т.к. бинарное устройсво инрефейсов нигде не прописано
>Что еще?
стандарт гарантирует бинарное представление для некоторого подмножетсва типов, говоря по простому - это примитивные типы и структуры из примитивных типов (или из таких же структур в них не может быть виртуальности, вроде конструкторов деструкторов тоже, но я не помню точно, по-умному такие типы называются - POD типы. Может быть, есть еще какой-то нюанс с выравниванием, но насколлько я помню, во всяком случае для фиксированной аппаратной архитекруты все детерминировано однозначно.
> Тут интересует, что можно делать по факту (char = 8 bit потому что всегда равно
...
>а что по какому стандарту (размер int 32 bit потому что win32)?
ни по какому, но по факту по-моему по другому сейчас и не будет, можно в принципе параноидально описывать типы как int32_t (ну или свои определять под разными дефайнами но имхо это уже перебор
>Почему endian с обоих сторон dll одинаковый?
потому что win32 везде

Dasar

>Почему endian с обоих сторон dll одинаковый?
потому что win32 везде
потому что компьютер(процессор) один и тот же.
а endian зависит от процессора.

evolet

тогда рекомендуется оформлять ее как com-библиотеку, это позволит не только ее вызывать из любого С++-компилятора, но вообще из любого языка (дельфи, .net, java и т.д.)
кста, тогда дополнение скажу
для COM интерфесов бинарное устройство определено (майкрософтом и что не подходит типа считается не COM интерфейсом, но по факту бинарно они устроены так же как и абстракные классы в ms компиляторе

evolet

ну да, так сказать правильнее будет

Dasar

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

Serab

стандарт гарантирует бинарное представление для некоторого подмножетсва типов, говоря по простому - это примитивные типы и структуры из примитивных типов (или из таких же структур в них не может быть виртуальности, вроде конструкторов деструкторов тоже, но я не помню точно, по-умному такие типы называются - POD типы.
POD (Plain Old Data) типы тут ни при чем. Размещение в памяти и для нормальных классов, естественно стандартизовано, потому что иначе писать программы было бы невозможно.
Для POD-типов не происходит инициализации для оператора new, да. Еще можно что-то придумать. Но к выравниванию отношения они не имеют.
vtbl-интерфейсы понимают многие языке и кроме C++ (Visual Basic, например, на C, конечно, можно накатать, да и если компилить idl, то там обертки будут созданы).

Maurog

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

struct A
{
};

какой sizeof у этой структуры по стандарту? :)

Andbar

vtbl-интерфейсы понимают многие языке и кроме C++ (Visual Basic, например, на C, конечно, можно накатать, да и если компилить idl, то там обертки будут созданы).
При этом приходится ориентироваться на конкретный способ межмодульных связей. Если же выбранный компилятор C++ её не поддерживает и использует несовместимую реализацию классов, то придётся либо использовать другой компилятор, либо использовать С-шную обёртку.

erotic

какой sizeof у этой структуры по стандарту?
Я почему-то думал, что должен быть 1 (т.к. 0 было бы плохо). Однако gcc пишет 0, а g++ 1 :shocked:

Serab

А если массив их создать, что напишет?

Andbar

Я почему-то думал, что должен быть 1 (т.к. 0 было бы плохо). Однако gcc пишет 0, а g++ 1 :shocked:
Интересно...
C:\temp>"%VS90COMNTOOLS%vsvars32.bat"&cl /EHsc size.c
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

size.c
size.c(6) : error C2016: C requires that a struct or union has at least one member
size.c(7) : error C2065: 'A' : undeclared identifier

C:\temp>type size.c
#include<stdio.h>
int main
{
struct A
{
};
printf("%d\n", sizeof(A;
}
C:\temp>ren size.c size.cpp


C:\temp>"%VS90COMNTOOLS%vsvars32.bat"&cl /EHsc size.cpp
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

size.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.

/out:size.exe
size.obj

C:\temp>size.exe
1

lada05

Интересно...
а что не так? разные компиляторы, и возможно поведение не определено в стандарте.

erotic

size.c(7) : error C2065: 'A' : undeclared identifier
Мне пришлось написать sizeof(struct A чтобы скомпилилось, но про отсутствие членов не было ошибок.

Realist

Поясни пожалуйста. Использование dll предполагается именно что на C++. Могут ли разные 32-bit компиляторы по-разному понимать указатель на таблицу виртуальных методов?

Dasar

Поясни пожалуйста. Использование dll предполагается именно что на C++. Могут ли разные 32-bit компиляторы по-разному понимать указатель на таблицу виртуальных методов?
могут конечно, т.к. в стандарте на C/C++ - реализация вообще никак не фиксируется.

Realist

естественно стандартизовано
Что ты имеешь ввиду? Что все поля в структуре выровнены по границе слова?

Dasar

Размещение в памяти и для нормальных классов, естественно стандартизовано, потому что иначе писать программы было бы невозможно.
ссылку, пожалуйста, на это место стандарта

Realist

Отлично. Может, есть какой другой стандарт на это? Или всего один естественный способ, как это может быть? Ну вот, например, я недавно узнал, что на размеры основных типов есть соглашения ILP64, LP64 и пр. Поэтому можно говорить, что в моей ситуации моя dll будет соответствовать ILP32, а другого в win32 de-facto нет.

Dasar

Поэтому можно говорить, что в моей ситуации моя dll будет соответствовать ILP32,
если у тебя только С++ и только win32, то стандартом можешь считать microsoft-овский компилятор.
intel компилятор совместим с microsoft-овским; всякие borland, watcom и т.д. имеют очень маленькую нишу, gcc вроде тоже.

Realist

То есть я могу реально в интерфейсе структуры и объекты гонять? Просто потому, что win32 и "так принято"?

Dasar

То есть я могу реально в интерфейсе структуры и объекты гонять? Просто потому, что win32 и "так принято"?
в целом, да.
но надо еще помнить, что у каждой dll-ки свой менеджер памяти, поэтому объекты(структуры, массивы и т.д.) должны удаляться той же dll-кой, что и были созданы

Realist

То есть, например, std::string я не могу вернуть? Но могу вернуть указатель при условии, что также предоставлю функцию типа void release(std::string *)?
Все-таки я никак не могу взять в толк, как люди живут? Пишут на COM? Пишут под один компилятор и не парятся или пишут абы как, а потом раз в полгода неделю дебужат мистические падения?

Dasar

Все-таки я никак не могу взять в толк, как люди живут? Пишут на COM? Пишут под один компилятор и не парятся или пишут абы как, а потом раз в полгода неделю дебужат мистические падения?
1. не пишут на С++
2. пишут на COM
3. пишут почти на COM (соглашения используются Com-овские, но не используется регистрация)
4. пишут абы как
5. пишут либы (а не dll) под конкретный компилятор
6. раздают исходники

Dasar

То есть, например, std::string я не могу вернуть? Но могу вернуть указатель при условии, что также предоставлю функцию типа void release(std::string *)?
да
типа того

amkharchenko

1. не пишут на С++

So true!

evolet

имхо: ху..во живут, если в целом... :)
std::string (как и указатели на него) нельзя передавать в основном по другой причине - исполльзовать разные реализации stl'а вроде это распростаненная практика, м.б. я и гоню, но имхо stlport субъективно используют чуть ли не в половине мест, а как ты понимаешь, в разнах реализациях stl'я рализация std::string может быть разная и если допустим ты скомпилишь свою либу с ms штатной stl, а пользоваться будут прогой с stlport, то, я думаю, 100% работать не будет
если для win32 заложиться на ms компилятор в принципе можно (хотя тут надо поботать тему, что он может сам поменять в зависимости от уровня оптимизации и других ключей компиляции то заклазываться на определенную реализацию stl - нельзя!, и => std::string, к большому сожалению, вылетает...

evolet

раз в полгода неделю дебужат мистические падения
бывает чаще, бывает дольше!
(во всяком случае если не одновременно, то точно бывает)
Оставить комментарий
Имя или ник:
Комментарий: