Здравствуйте, adontz, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>Как выйдти из положения? Dll-ка не моя, поэтому использовать другие соглашения о вызове не могу, в то же время хочу использовать Вашу библиотеку, имхо очень удобная.
A>Ну так просто замени везде в библиотеке WINAPI на на что надо. Правда её тогда нельзя будет использовать с системными функциями.
Библиотека (.dll) не моя, менять ничего не могу. Даже хедера нет, есть только дока с описанием контекста функций.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, ssi, Вы писали:
ssi>>Библиотека (.dll) не моя, менять ничего не могу. Даже хедера нет, есть только дока с описанием контекста функций.
A>В библиотеке которой посвящён этот топик, а не в той которую ты хочешь подключить
А>>Как выйдти из положения? Dll-ка не моя, поэтому использовать другие соглашения о вызове не могу, в то же время хочу использовать Вашу библиотеку, имхо очень удобная.
A>Ну так просто замени везде в библиотеке WINAPI на на что надо. Правда её тогда нельзя будет использовать с системными функциями.
Ну ладно, ладно, уговорили Не надо так прям вот все менять.
Итак, версия 1.3.0 бета.
Список изменений:
1. Добавлена поддержка конвенций вызова. Непосредственно в библиотеке поддерживаются WINAPI и __cdecl.
Итак, как все это работает. За поддержку встроенных конвенций отвечают макросы
#define DL_NO_STDCALL // не инастанцировать поддержку winapi соглашений о вызовах#define DL_USE_CDECL // инстанцировать поддержку __cdecl (по умолчанию отключено)
За поддержку вообще любых конценций отвечают макросы
Назначение и параметры макросов DL_DECLARE_FUN_xxx_CC аналогичны DL_DECLARE_FUN_xxx, за исключением того, что первым параметром добавляется конвенция о вызове функции. Т.о., на самом деле это generic интерфейс к библиотеке, которым пользуются все остальные макросы.
Так фактически будет повторение синтаксиса определения функции в С... Как вам это, обсудим? Последствия очевидны — обломинго при компиляции старых исходников.
И еще вопрос: если функция возвращает сишную структуру, то почему я не могу использовать макросы DL_DECLARE_FUN и DL_DECLARE_FUN_ERR? Компилятор выдает ошибки С2993 и С2975 на класс CFunProxyValuePolicy?
Получается, что в этом случае единственный способ узнать об ошибке это использовать DL_DECLARE_FUN_THROW, что ИМХО не очень удобно — ставить вокруг каждого вызова функции из dll-ки блок try-catch.
А>Раз уж мы определили дефайном DL_USE_CDECL, зачем использовать DL_DECLARE_FUN_CC(__cdecl, ...) вместо обычного DL_DECLARE_FUN()?
DL_DECLARE_FUN подразумевает использование соглашений WINAPI. DL_DECLARE_FUN_CC позволяет явно указать соглашения. Често говоря, не понимаю недоразумения.
А>или так нельзя: А>
Можно, для этого DL_DECLARE_FUN_CC и нужно. дефайн DL_USE_CDECL не изменяет конвенций по умолчанию, он лишь добавляет поддержку __cdecl в DL_DECLARE_FUN_CC. Думаю, этот код говорит сам за себя:
А>И еще вопрос: если функция возвращает сишную структуру, то почему я не могу использовать макросы DL_DECLARE_FUN и DL_DECLARE_FUN_ERR? Компилятор выдает ошибки С2993 и С2975 на класс CFunProxyValuePolicy?
В параметры шаблона стратегии эта штука передается как template<class R, R value = R()>. Т.е., допустимы только интегральные типы и указатели — все то, что принимает значения константы. Единственная проблема со стратегией CFunProxyValuePolicy — это то, что для, например, HANDLE, нельзя передать -1 как значение ошибки. В случае HANDLE это решается тем, что оно в вин32 не может также принимать и значение 0, хотя это, конечно, и не очень красиво получается. Если кто-нибудь предложит красивое решение проблемы — я буду только рад...
А вообще, если често.. Возвращать из экспортируемой функции структуру по значению... ну, я бы за это кастрировал, если только этому нет _очень_ веских оснований. И это меньшее, что можно сделать, нельзя допускать, чтобы такие люди размножались
А>Получается, что в этом случае единственный способ узнать об ошибке это использовать DL_DECLARE_FUN_THROW, что ИМХО не очень удобно — ставить вокруг каждого вызова функции из dll-ки блок try-catch.
Ровно так же это единственный способ узнать об ошибке в случае void функций — так что других вариантов тут нет. Инстанцировать шаблон с типизированым параметром можно только интегральным литералом, указателем на объект с external linkage (например, функцию), либо NULL для указателя. Если у вас есть какие-то лучшие предложения (с реализацией, конечно, напредлагать просто так и я сам могу) — u are welcome.
А>Получается, что в этом случае единственный способ узнать об ошибке это использовать DL_DECLARE_FUN_THROW, что ИМХО не очень удобно — ставить вокруг каждого вызова функции из dll-ки блок try-catch.
Совсем забыл сказать — у вас еще есть вариант использовать DL_DECLARE_FUN_ERR_POLICY(name_id, r, p, pl), где задать свою политику, допускающую возвращение структур. Например, такую:
Штука понравилась, но не смог сослаться на функцию с переменным количеством параметров, в следствие чего не стал использовать для решения одной задачи. Обыдна... Может я чего не досмотрел???
Здравствуйте, Plague, Вы писали:
P>Штука понравилась, но не смог сослаться на функцию с переменным количеством параметров, в следствие чего не стал использовать для решения одной задачи. Обыдна... Может я чего не досмотрел???
STDCALL использовавшийся до последнего времени в библиотеке не поддерживает переменное число аргументов. Сейчас есть поддержка нескольких конвенций. Переменное число аргументов поддерживает CDECL
P>>Штука понравилась, но не смог сослаться на функцию с переменным количеством параметров, в следствие чего не стал использовать для решения одной задачи. Обыдна... Может я чего не досмотрел???
Нет, все верно. stdcall традиционно не поддерживает переменное число агрументов, поскольку стек очищает сама функция. cdecl может поддерживать переменное число агрументов, однако в библиотеке переменное число агрументов не поддерживается вообще. Используйте va функции для передачи переменного числа агрументов, если оные, конечно, имеются. Еще где-то в исходниках были еще варианты динамической загрузки — может там что поможет.
A>STDCALL использовавшийся до последнего времени в библиотеке не поддерживает переменное число аргументов. Сейчас есть поддержка нескольких конвенций. Переменное число аргументов поддерживает CDECL
См. выше, это не так. Переменное число агрументов не может быть поддержано библиотекой архитектурно — для этого простыми методами не обойтись — надо подменять стек.
Здравствуйте, Andrew S, Вы писали:
AS>Нет, все верно. stdcall традиционно не поддерживает переменное число агрументов, поскольку стек очищает сама функция. cdecl может поддерживать переменное число агрументов, однако в библиотеке переменное число агрументов не поддерживается вообще. Используйте va функции для передачи переменного числа агрументов, если оные, конечно, имеются. Еще где-то в исходниках были еще варианты динамической загрузки — может там что поможет.
Просто есть DLL одной малоизвесной SQL базы данных, и было желание написать "враппер", т.к. вся работа шла через одну DLL. Так там экспортировались функции с переменным количеством аргументов , было б неплохо хотябы "подпорку" написать, что для всех как обычно функций, а для таких "с извратами". Чтоб для можно было использовать для _любых_ С-функций.
AS>>Нет, все верно. stdcall традиционно не поддерживает переменное число агрументов, поскольку стек очищает сама функция. cdecl может поддерживать переменное число агрументов, однако в библиотеке переменное число агрументов не поддерживается вообще. Используйте va функции для передачи переменного числа агрументов, если оные, конечно, имеются. Еще где-то в исходниках были еще варианты динамической загрузки — может там что поможет.
P>Просто есть DLL одной малоизвесной SQL базы данных, и было желание написать "враппер", т.к. вся работа шла через одну DLL. Так там экспортировались функции с переменным количеством аргументов , было б неплохо хотябы "подпорку" написать, что для всех как обычно функций, а для таких "с извратами". Чтоб для можно было использовать для _любых_ С-функций.
Не получится. Проблема в прокси — там требуется знать количество параметров при определении. Ну и сама идеология "ленивой" загрузки не позволяет это делать. Впрочем, все ясно из кода...
Здравствуйте, Andrew S, Вы писали:
AS>Не получится. Проблема в прокси — там требуется знать количество параметров при определении. Ну и сама идеология "ленивой" загрузки не позволяет это делать. Впрочем, все ясно из кода...
В принципе некоторое количество ассемблера решило бы проблему
AS>>Не получится. Проблема в прокси — там требуется знать количество параметров при определении. Ну и сама идеология "ленивой" загрузки не позволяет это делать. Впрочем, все ясно из кода...
A>В принципе некоторое количество ассемблера решило бы проблему
Некоторое количество машинных команд может решить любую программистскую проблему. Вот только вопрос в том, как правильно собрать эти команды. В рамках библиотеки использовать ассемблерные вставки, очевидно, смысла нет — 99% задач решается и без них, для остального есть поддерживаемый компилятором делейлоад, либо резолвинг ручками. Смысла терять в переносимости библиотеки из-за сомнительной поддержки переменного числа параметров я не вижу Написать ручками обертку на загружаемую библиотеку один раз — имхо не проблема.
Поскольку сразу через 2 версии, то в порядке очереди.
Итак, версия 1.3.0. (предыдущая)
Список изменений:
1. Добавлена поддержка конвенций вызова. Непосредственно в библиотеке поддерживаются WINAPI и __cdecl.
Итак, как все это работает. За поддержку встроенных конвенций отвечают макросы
#define DL_NO_STDCALL // не инстанцировать поддержку winapi соглашений о вызовах#define DL_USE_CDECL // инстанцировать поддержку __cdecl (по умолчанию отключено)
За поддержку вообще любых конценций отвечают макросы
Назначение и параметры макросов DL_DECLARE_FUN_xxx_CC аналогичны DL_DECLARE_FUN_xxx, за исключением того, что первым параметром добавляется конвенция о вызове функции. Т.о., на самом деле это generic интерфейс к библиотеке, которым пользуются все остальные макросы.
1. Добавлена поддержка числовых идентификаторов функций (by ord), а также возможность переименования (алиаса) для функций. Для этого определен расширенный набор макросов DL_DECLARE_FUN_...._EX. Список параметров аналогичен обычному набору, за исключением необходимости задавать и имя , и идентификатор функции (ижентификатор это то, что получает GetProcAddr).
Например,
2. Добавлена политика ошибок CFunProxyDefPolicy — в отличие от CFunProxyValuePolicy, позволяет работать не только со встроенными типами. Данная политика используется в макросах DL_DECLARE_FUN(_EX) вместо CFunProxyValuePolicy<ret_type>.