Создать DLL на С++ | |
---|---|
Перминов Игорь Автор Сообщений: 1591 Откуда: Красная Орловка Дата регистрации: 16.09.2001 |
Коллеги, всем доброго дня.
Писал DLL на Borland С++ Builder - все нормально было. Теперь появилась нужда написать DLL, использую VS 2015 и C++. Создал проект, подготовил CPP и H файлы, собрал решение в DLL. Из VFP:
Message: Cannot find entry point _MyAdd in the DLL. ********************* CPP файл:
Вырезка из MAP файла:
Тогда где, что неправильно, может кто поможет разобраться. ------------------ Без коментариев.. Исправлено 2 раз(а). Последнее : Перминов Игорь, 23.03.17 10:39 |
Re: Создать DLL на С++ | |
---|---|
Рома Сообщений: 1079 Дата регистрации: 06.06.2001 |
_MyAdd в таблице экспорта dll будет без подчеркивания. "_" в объектном файле - соглашение о вызове
Для stdcall должно получиться _MyAdd@16 Т.е. нужно
Вот правильная сигнатура для твоей функции (@ не нужно, так как нет в C функции указателя у параметров)
Исправлено 3 раз(а). Последнее : Рома, 23.03.17 17:41 |
Re: Создать DLL на С++ | |
---|---|
Перминов Игорь Автор Сообщений: 1591 Откуда: Красная Орловка Дата регистрации: 16.09.2001 |
Получилось:
H файл:
CPP файл:
Декларирование в VFP:
------------------ Без коментариев.. |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Непонятно назначение вашей функции, что делает и что возвращает.
Обычно функции API возвращают 0 при неудаче, поэтому и отпадает необходимость в TRY. |
Re: Создать DLL на С++ | |
---|---|
Перминов Игорь Автор Сообщений: 1591 Откуда: Красная Орловка Дата регистрации: 16.09.2001 |
Не совсем понятен Ваш вопрос:
Вы имеете в виду MyAdd()? или вот это:
------------------ Без коментариев.. |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Да, непонятно назначение вашей довольно громоздкой конструкции - что делает, что за параметры принимает, что возвращает, почему в TRY.
Исправлено 1 раз(а). Последнее : lulgu, 24.03.17 12:02 |
Re: Создать DLL на С++ | |
---|---|
Перминов Игорь Автор Сообщений: 1591 Откуда: Красная Орловка Дата регистрации: 16.09.2001 |
Делает только то, что тестирует функцию из DLL скомпонованный в VS 2015. А то что обернул так громоздко - пока голову ломал (заколебался на кнопку Продолжить давить), почему генерировалась ошибка Cannot find entry point _MyAdd in the DLL". Теперь буду дальше писать в VS то, что задумал для использования в VFP. ------------------ Без коментариев.. |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Вам надо предусмотреть стандартный возврат 0 при ошибке.
|
Re: Создать DLL на С++ | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Боже мой, какой идиотизм... Да, мой друг, это клинический случай. Когда функция сложения возвращает 0 "в случае ошибки" - тут медицина бессильна. Для более адекватных читателей - try в коде тёзки ловит прежде всего ошибки при декларировании функции и при попытке её вызова. И лишь в самую последнюю очередь ошибки которые могли произойти ВНУТРИ этой функции. ------------------ WBR, Igor |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Ну да.
Все Winapi, в объеме MSDN это сплошной идиотизм, и каждый раз все DECLARE обвешиваются траями. Вам дай волю, и вы со своей религией каждую запятую обернете в TRY. |
Re: Создать DLL на С++ | |
---|---|
pasha_usue Сообщений: 3650 Откуда: Е-бург Дата регистрации: 06.10.2006 |
Вы себе придумали догму, которой в WINAPI нет. Во-первых, ошибка это не всегда ноль. Очень часто для обозначения ошибки WINAPI возвращает значения меньше нуля для знаковых возвращаемых данных (DialogBox, GetMessage). И есть ряд функций, которые вообще не возвращают ошибку, например: AnsiLower AnsiUpper CountClipoardFormats CountVoiceNotes EqualRect EqualRgn MakeLong Исправлено 1 раз(а). Последнее : pasha_usue, 24.03.17 14:46 |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Ваши примеры только подтверждают общее правило. Если 0 по каким-либо причинам не подходит, то ничто не запрещает использовать другую цифру. И эти функции не оборачивают в TRY, даже если они ничего не возвращают. Если бы ТС не обернул свою конструкцию в трей, то он шел бы по шагам и отлавливал бы свои ошибки. Но TRY не позволил ему локализовать их. |
Re: Создать DLL на С++ | |
---|---|
pasha_usue Сообщений: 3650 Откуда: Е-бург Дата регистрации: 06.10.2006 |
Какую цифру для возврата ошибки использует функция MakeLong? А головой подумать? ТС отлаживал именно объявление функции в C++. После каждой попытки запуска ему надо было перекомпилировать DLL. И для того чтобы файл DLL был не занят на момент перекомпиляции, он в блоке FINALLY гарантированно этот файл высвобождал. Соответственно, он экономил кучу времени, что б вручную не освобождать DLL-ку. Ну вы если сами не догоняете, вы спросите лучше вежливо. Исправлено 1 раз(а). Последнее : pasha_usue, 24.03.17 15:43 |
Re: Создать DLL на С++ | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Человеку не понимающему смысл структурной обработки ошибок бессмысленно что-либо пояснять
Да, в нормальной программе использующей структурную обработку ошибок "любая запятая" находится внутри блока try. Более того, некоторые "запятые" находятся внутри 2, 3 а то и 4-х вложенных блоков try. И это правильно. Да, декларации функций из стандартных виндовых библиотек так тщательно "проверять" не требуется - крайне маловероятно что в работающей Windows системе не будет найдена библиотека user32.dll или kernel32.dll - при их использовании главное не ошибиться с параметрами (не передать, к примеру, адрес указывающий на невыделенную память - хотя и такую ошибку фокс попытается "сгладить" - он сам "обвешивает" любой вызов внешней библиотеки своим внутренним try...catch обработчиком) - тогда шанс получить ошибку во время исполнения минимален, и её вполне может ловить обработчик ошибок самого верхнего уровня - тот что ловит все "непредусмотренные" ошибки (например самый внешний try в случае использования этого подхода к обработке ошибок). Однако когда речь заходит про какие-то "левые" (не системные) библиотеки, то такого рода проверка не будет лишней. И сама библиотека может отсутствовать, и экспортируемая функция может отсутствовать или отличаться параметрами от того как мы её описали - собственно говоря вся эта тема из того и выросла - что в dll НЕ БЫЛО экспортируемой функции с нужным именем. А по поводу "возвращаемых значений" - 0 как "признак ошибки" не так уж и "повсеместно" используется. Он появляется в тех функциях которые возвращают BOOL значение и это именно "статус выполнения", и, иногда, указатели. При том, формально, это РАЗНЫЕ нули. FALSE в первом случае и NULL во втором. А те функции что возвращают хендлы - там как раз -1 является признаком ошибки, т.к. именно таково значение константы INVALID_HANDLE_VALUE. А есть ещё куча функций возвращающих HRESULT - и там, о боже, какой ужас именно значение 0 является признаком УСПЕШНОГО выполнения. А разнообразные "ошибки" представлены отрицательными значениями... Вообще трудно найти более убогую и непоследовательную "систему соглашений" о том как именно функция должна "сигнализировать" вызывающему коду о проблемах, нежели то что имеется в WindowsAPI - исторические причины, разнобой в разных командах писавших это хозяйство и мы имеем то что имеем - трэш, угар и содомию - никакого "единого подхода". Вот в .NET есть единый подход - там любая "проблема" в вызываемом коде ДОЛЖНА сопровождаться генерацией исключения, и, соответственно, в вызывающем коде "ловиться" при помощи блока try ... catch. И это, кстати, строго, последовательно и правильно В общем можно констатировать что очередной раз воинствующее невежество село в лужу. ------------------ WBR, Igor |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
pasha_usue
Чуть-чуть выше я выложил простой типовой код для функций Winapi, который делает то же самое. Что качается вашего примера, то функций в Winapi тыщи и я не занимаюсь пискомеряньем. Igor Korolyov Ваша способность заболтать любой вопрос порой просто удивляет. Ладно еще, что не добавили: - "Волга впадает в Каспийское море". |
Re: Создать DLL на С++ | |
---|---|
pasha_usue Сообщений: 3650 Откуда: Е-бург Дата регистрации: 06.10.2006 |
Что то же самое? При CANCEL высвобождает файл? Вы лукавите и виляете. Просто потому что в каждом пункте "сели в лужу". Виляете. И виляете и лукавите одновременно. |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
pasha_usue
Похоже, у вас опять очень быстро истощились аргументы, ненадолго вас хватает. Этот типовой код подходит как обертка для большинства функций Winapi. Мало того, даже в такой компактной обертке в Фоксе нет необходимости. |
Re: Создать DLL на С++ | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Подходит. Для многих винАПИ функций вполне. Именно так - для большинства винАПИ функций (да и не только WinAPI) "обёртки" не нужны. Сама по себе команда DECLARE-DLL и создаёт "обёртку" позволяющую из фокса вызвать библиотечную функцию. Всё прочее - это уже комбинация нескольких функций для получения требуемого результата. Ну или скрытие нюансов трансформации параметров (структуры, или буфер памяти для возврата строки). И что далее? В смысл начального вопроса вникнуть никак? И в банальный факт того что именно кодировалась в примере - уж проще сишного кода и придумать сложно... Зато подмечать то чего нет, и влазить в спор о том чего не понимаете - это завсегда пожалуйста. ------------------ WBR, Igor |
Re: Создать DLL на С++ | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Igor Korolyov
Если код подходит, то что вас взвинтило, что даже о достоинстве забыли? Так нужна для DECLARE обертка или нет? И зачем, по вашему, DECLARE нужно заворачивать в TRY, если она и так "создает обертку"? |
Re: Создать DLL на С++ | |
---|---|
Перминов Игорь Автор Сообщений: 1591 Откуда: Красная Орловка Дата регистрации: 16.09.2001 |
Не думал, что из такого примера можно раздуть слона. Мой пример просто тестирует вызов MyAdd() из мной же написанной DLL на VC (C++) - и все. Так что должна вернуть функция которая складывает 2 числа? 0 (ноль) или 1 (один). Или может добавить третий параметр в котором будет возвращен результат сложения - блиииин. Результатом возврата 0 или 1 может быть только логический результат выполнения некоторого действия а не принадлежность к API, т.е. например if (IsConnect) или if (a>b), and etc. API это набор функций, классов, объектов, форм. Вот когда мной задуманное будет реализовано в некий функционал, тогда всю эту сущность можно будет, с большой натяжкой, назвать API (application programming interface). ------------------ Без коментариев.. Исправлено 2 раз(а). Последнее : Перминов Игорь, 24.03.17 18:01 |
© 2000-2024 Fox Club  |