Правильно обьявить функцию dll

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Правильно обьявить функцию dll

Сообщение bodja » 19.02.2011 (Сб) 1:28

Уважаемые ,нужна ваша помощь.
Есть некая ДЛЛка.
Есть для нее обьявленная функция на Си
int Codec(signed short int* in20, unsigned char* out10)
она принимает массив из 20 чисел signed short int и выдает массив из 10 чисел char,я так понимаю.
Попытки с вариациями типа
Private Declare Function Codec Lib "Сoder.dll" (in As Any, out As Any) As Long
ни к чему не привели,выдает ошибку.
Буду признателен,если кто правильно переведет,если это вообще возможно.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Правильно обьявить функцию dll

Сообщение Хакер » 19.02.2011 (Сб) 7:11

bodja писал(а):Private Declare Function Codec Lib "Сoder.dll" (in As Any, out As Any) As Long

Такой вариант тоже правилен. Просто ты не соображаешь, что и как передаётся.
Такой вариант типобезопасен:
Код: Выделить всё
Private Declare Function Codec Lib "Сoder.dll" (ByRef in20 As Integer, ByRef out10 As Byte) As Long


Если будешь дальше оформлять свои сообщения как попало, будешь наказан :!: .
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Re: Правильно обьявить функцию dll

Сообщение bodja » 19.02.2011 (Сб) 14:41

Хорошо вот пробую так
Код: Выделить всё

Private Declare Function Codeс Lib "Coder.dll" (ByRef in20 As Integer,ByRef out10 As Byte) As Long

Private Sub Form_Load()
Dim in20buf(0 To 19) As Integer
Dim out10buf(0 To 9) As Byte
Dim g As Long
For x = 0 To 19
in20buf(x) = 1000
Next
g = Codec(in20buf(0), out10buf(0))
End Sub


Выдает ошибку 453
Cant find DLL entry point Codec in Coder.dll


Еще пытался зарегестрировать библиотеку через regsvr32 ,тоже выдает ошибку

Coder.dll была загружена,но найти точку входа для DDLRegisterServer не удалось.
Зарегестрировать этот файл невозможно.


Возможно VB6 хочет работать только с зарегестрироваными библиотеками?
Или у меня действительно туго с пониманием ,что и как передается? :oops:

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Правильно обьявить функцию dll

Сообщение Debugger » 19.02.2011 (Сб) 14:49

Некоторые библиотеки не нуждаются в регистрации.
Cant find DLL entry point Codec in Coder.dll

Это ошибка возникает из-за целого букета причин. Попробуй сохранить проект в одной папке с dll-кой и запустить его. Удостоверься, что функция называется "Codec", а не "codec" или как-нибудь "codec_encode".
Возможно, библиотеке чего-то хочется (дополнительных файлов, других библиотек), и она не может инициализироваться, из-за чего VB6 и выдает такую ошибку.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Правильно обьявить функцию dll

Сообщение Хакер » 19.02.2011 (Сб) 15:57

bodja писал(а):Еще пытался зарегестрировать библиотеку через regsvr32 ,тоже выдает ошибку

Ещё попытайся проиграть библиотеку Winamp-ом.

bodja писал(а):Или у меня действительно туго с пониманием ,что и как передается?

Действительно.

Debugger писал(а):Некоторые библиотеки не нуждаются в регистрации.

Лишь некоторые нуждаются. Остальные не нуждаются. Регистрация нужна для создания COM-классов через CoCreateInstance. Только и всего. У регистрации больше нет никакого предназначения, кроме этого. И в данном случае COM-ом не пахнет.

Debugger писал(а):Это ошибка возникает из-за целого букета причин.

В данном случае это неправда.
Это «Can't find DLL file» возникает по целому букету причин, начиная от действительной невозможности найти файл, и вплоть до невозможности резолвинга зависимостей, ошибок внутри DllEntryPoint одной из библиотек в дереве зависимостей и так далее.
А «Can't find entry point» случается только по одному поводу: kernel32!GetProcAddress не смогла обнаружить запрашиваемую экспортируемую сущность. То есть, за исключением одного редкого случая, сущности в DLL-шке с таким именем нет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Re: Правильно обьявить функцию dll

Сообщение bodja » 19.02.2011 (Сб) 16:09

В одной папке с проектом сохранял ,вообще не видело.
Потом залил в System32 увидело :)

Смотрел через Depedency Walker функции и параметры совпадают.
По связям только Kernel32 и NTDLL ,Walker не ругается.

В целом функцию сверху я приводил для примера,для простоты понимания вопроса.
Сама ДЛЛка находится здесь
Там же описания и ее исходники.
Я думаю имея исходники ,ее можно переделать даже на ActiveX.
Но она написана на С++ ,язык этот я немного знаю ,так как пишу на нем под ARM контроллеры,
но для ПК у меня совсем туго с ним :alien:
Поэтому пока это сделать не в моих силах.
Буду рад любой помощи. :cry:

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Правильно обьявить функцию dll

Сообщение Хакер » 19.02.2011 (Сб) 16:20

bodja писал(а):В одной папке с проектом сохранял ,вообще не видело.

Когда говорят «в одной папке с проектом», предполагают, что проект скомпилирован, или не скомпилирован, но папка проекта является текущей рабочей папкой процесса. У тебя, видимо, никакое условие не соблюдено.

bodja писал(а):Смотрел через Depedency Walker функции и параметры совпадают.

Регистр символов сопадает?



P.S. Посмотрел библиотеку. Где там Codec, когда там только две функции: ?Gsm610Decode@@YAHPAEPAF@Z и ?Gsm610Encode@@YAHPAFPAE@Z.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Re: Правильно обьявить функцию dll

Сообщение bodja » 19.02.2011 (Сб) 16:37

Хакер писал(а):Когда говорят «в одной папке с проектом», предполагают, что проект скомпилирован, или не скомпилирован, но папка проекта является текущей рабочей папкой процесса. У тебя, видимо, никакое условие не соблюдено..

Проект не компилировал.Так уже выдавало ошибку,не видел смысла.В целом уже это неважно

Регистр символов сопадает?

Да.


P.S. Посмотрел библиотеку. Где там Codec, когда там только две функции: ?Gsm610Decode@@YAHPAEPAF@Z и ?Gsm610Encode@@YAHPAFPAE@Z.

Я выше писал ,что написал в качестве примера.
Давайте так ,если в точности
Код: Выделить всё
Private Declare Function Gsm610Encode Lib "gsmcodec.dll" (ByRef in20 As Integer, ByRef out10 As Byte) As Long

Private Sub Form_Load()
Dim in20buf(0 To 159) As Integer
Dim out10buf(0 To 32) As Byte
Dim g As Long
For x = 0 To 159
in20buf(x) = 1000
Next
g = Gsm610Encode(in20buf(0), out10buf(0))
End Sub


ЗЫ Клацаете по этому ?Gsm610Encode@@YAHPAFPAE@Z левой потом правой кнопкой мыши ,потом Undecorate C++ Function.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Правильно обьявить функцию dll

Сообщение Хакер » 19.02.2011 (Сб) 16:46

bodja писал(а):ЗЫ Клацаете по этому ?Gsm610Encode@@YAHPAFPAE@Z левой потом правой кнопкой мыши ,потом Undecorate C++ Function.

Ты шутник что-ли? Зачем мне undecorated имя? Сущность в таблице экспорта имеет именно такое имя, какое я тебе написал. И GetProcAddress не будет делать размангливание имени. Поэтому крайне глупо указывать раскодированное имя и удивляться, а почему возникает ошибка «такая сущность не найдена».

Кроме того, это cdecl-функции. VB умеет вызывать только stdcall-функции. Так что либо тебе придётся изобретать переходник (что само по себе не сложно, но с твоими знаниями...), либо педелывай сишный проект, так, чтобы функции стали stdcall-ными.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Re: Правильно обьявить функцию dll

Сообщение bodja » 19.02.2011 (Сб) 16:56

Хакер писал(а):Кроме того, это cdecl-функции. VB умеет вызывать только stdcall-функции. Так что либо тебе придётся изобретать переходник (что само по себе не сложно, но с твоими знаниями...), либо педелывай сишный проект, так, чтобы функции стали stdcall-ными.

Ну это на данный момент выше моего понимания разницы этих функций :D
Спасибо за результат ошибки.
Значит эта ДЛЛка к VB6 пока не лепится ?
Ну и тогда следующий вопрос ,где можно почитать внятную статью ,чтобы функции стали stdcall-ными.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Правильно обьявить функцию dll

Сообщение Хакер » 19.02.2011 (Сб) 17:20

bodja писал(а):Значит эта ДЛЛка к VB6 пока не лепится ?

Через специальный переходник можно.

bodja писал(а):Ну и тогда следующий вопрос ,где можно почитать внятную статью ,чтобы функции стали stdcall-ными.

От того, что ты что-то прочитаешь, используемое соглашение не поменяется. Вообще, позоришь отрасль: уж кому-кому, только не разработчику под микропроцессоры/микроконтроллеры не знать о регистрах и стеке и всевозможных вариациях передачи параметров через регистры и стек.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Re: Правильно обьявить функцию dll

Сообщение bodja » 19.02.2011 (Сб) 19:18

От того, что ты что-то прочитаешь, используемое соглашение не поменяется. Вообще, позоришь отрасль: уж кому-кому, только не разработчику под микропроцессоры/микроконтроллеры не знать о регистрах и стеке и всевозможных вариациях передачи параметров через регистры и стек.


Уважаемый Хакер,
если ваша задача состоит в том,чтобы не сколько помочь в решении вопроса ,сколько наступить мне на любимый мозоль,то наверное не получится.
Я писал не асме для AVR ,когда еще ARM-и и не пахло,и прекрасно знаю что такое стек ,регистры как рабочие так и ввода-вывода,флаги ,таблица прерываний ,шина и т.д.К тому же на разных ядрах ,все это по разному.
И не раз помогал Сишникам привести их код к реалиям железа,так как компилятор решал вышеприведенные вопросы за них через визарды и стартапы.
Поверте мне ,большинство кто пишет на си,бейсике,паскале для контроллеров до сих пор незнают про соглашения ,регистрах ,стеке,
аппаратной периферии ,так как это решалось компилятором.
Причем написание программы - это только 30%решения вопроса,есть еще куча железа подключенных к ногам контроллера ,вот там начинается электроника, и там же начинается у господ программистов полный ступор.
Так что позорить меня ораслью не нужно.
У меня нет сомнений ,что я плохо разбираюсь в этой теме и в этом вопросе,если бы разбирался хорошо я бы вопрос на этом форуме не задавал.И не нужно в каждом посте мне напоминать,что я плохо разбираюсь в этом вопросе- я не совсем тупой и тему создал не в разделе для профессионалов.
И я пришел не для того сюда ,чтобы померятся пиписьками,не тот уровень и не та цель.
Если охота померятся пиписьками касаемо контроллеров -не тот форум.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Правильно обьявить функцию dll

Сообщение Хакер » 19.02.2011 (Сб) 19:35

bodja писал(а):Уважаемый Хакер,
...
Я писал не асме для AVR ,когда еще ARM-и и не пахло,и

Уважаемый знаток истории микропроцессоров. Семейство AVR появились позже архитектуры ARM.

Я попрошу тебя не бравировать умением писать под микроконтроллеры. Оно меня не поражает: я сам отлично разбираюсь в них, а вот ты не можешь похвастаться обратым («ПК у меня совсем туго с ним»).

В общем, кувыркайся тогда сам.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Re: Правильно обьявить функцию dll

Сообщение bodja » 19.02.2011 (Сб) 22:21

Хакер писал(а):Уважаемый знаток истории микропроцессоров. Семейство AVR появились позже архитектуры ARM.

Да ну?
Зайдите в любой магазин радиодеталей ,спросите что у них появилось позже,если помнят.
Мне лично пришлось тогда из за бугра заказывать.

Оно меня не поражает: я сам отлично разбираюсь в них, а вот ты не можешь похвастаться обратым

Период когда я думал ,что все знаю и всех умнее я переболел,поэтому уже давно надоело хвастаться и доказывать.
Чесно -устал уже.Просто решаю задачи по ходу их поступления.Ну и от таких амбициозов как вы отстреливаюсь :D
что бы сильно катком не закатывали в асфальт. :D

В общем, кувыркайся тогда сам.

Ну ,мне не впервой ,эта задача лиш 5% из того что сделано и предстоит сделать.

Удачи.

hclubmk
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 240
Зарегистрирован: 19.06.2009 (Пт) 14:23
Откуда: От-туда

Re: Правильно обьявить функцию dll

Сообщение hclubmk » 19.02.2011 (Сб) 23:59

bodja
Глубоко не вникал, но если проблема с вызовом cdecl-функций из VB: класс для решения твоей задачи.
Научились ли Вы радоваться трудностям?

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Правильно обьявить функцию dll

Сообщение Vi » 21.02.2011 (Пн) 10:08

bodja писал(а):ЗЫ Клацаете по этому ?Gsm610Encode@@YAHPAFPAE@Z левой потом правой кнопкой мыши ,потом Undecorate C++ Function.


Код: Выделить всё
UNDNAME.EXE ?Gsm610Encode@@YAHPAFPAE@Z

>> ?Gsm610Encode@@YAHPAFPAE@Z == Gsm610Encode

UNDNAME.EXE -F ?Gsm610Encode@@YAHPAFPAE@Z

>> ?Gsm610Encode@@YAHPAFPAE@Z == int __cdecl Gsm610Encode(short *,unsigned char *)
Вот это слово __cdecl и определяет соглашение о вызове этого метода. Дело в том, что это стандартный вызов в С, и он применяется, если соглашение не указано. Если изменить это слово на __stdcall (или же вставить в определение функции), то ваша задача разрешится и эту функцию можно будет вызвать из VB.

Или ввести новую функцию в DLL с таким соглашением, в которой просто вызвать исходную cdecl-овскую. Т.е. оставить старую для совместимости.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

bodja
Новичок
Новичок
 
Сообщения: 40
Зарегистрирован: 02.04.2006 (Вс) 15:18
Откуда: Ukraina

Re: Правильно обьявить функцию dll

Сообщение bodja » 21.02.2011 (Пн) 22:48

hclubmk писал(а):bodja
Глубоко не вникал, но если проблема с вызовом cdecl-функций из VB:

Спс за наводку ,скачал ,глянул поискал еще пару примеров .
Дело в том что функции должны вызываться 100 раз в секунду (code/decode),плюс куча всяких асинхронных процессов,
и любые задержки будут заметны на звуке.Поэтому решил не напрягать прогу на VB дополнительными преобразованиями вызова функций.

Вот это слово __cdecl и определяет соглашение о вызове этого метода. Дело в том, что это стандартный вызов в С, и он применяется, если соглашение не указано. Если изменить это слово на __stdcall (или же вставить в определение функции), то ваша задача разрешится и эту функцию можно будет вызвать из VB.


Спасибо,я тут глянул Gsmcodec.cpp и Gsmcodec.h то в результате получается такое обявление
Код: Выделить всё
__declspec (dllexport) int Gsm610Decode(unsigned char* in33, signed short int* out160)

__declspec (dllexport) int Gsm610Encode(signed short int* in160, unsigned char* out33 )

Я почитал несколько статей по этому поводу
в итоге нужно было просто подсунуть линковщику def-файл с таким содержанием
Код: Выделить всё
    LIBRARY         "gsmcodec"

        DESCRIPTION    'Супер-мупер крутая либа :)'



    EXPORTS

        Gsm610Decode     @1
        Gsm610Encode     @2

Компилим... и песня :)
Однозначно так и не понял,почему так делает линковщик,у всех статей разные размышления по этому поводу,
но пример приводится один и тот же.
Есть еще в среде Proect > Settings.. > C/C++ > Category "Code Generation" > Calling conversion "__cdecl"
можно поменять "__cdecl" на __fastcall и __stdcall .Можно будет с ними поиграться позже ради академического интереса,
также обязательно попробую ваш способ.
Походу пока выбрасываю из исходников лишний функционал,прикручиваю к либе DirectX Sound и размышляю
как из либы асинхронно сообщить проге на VB о готовности данных.
А в целом как решил проблему написал выше.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 103

    TopList