Оказывается VB6 поддерживат вызов cdecl-функций

Модератор: Хакер

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

Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение Хакер » 04.02.2013 (Пн) 22:18

В общем, я тут выяснил, что VB штатно от природы умеет компилировать программы, вызывающие не только stdcall-функции из внешних DLL, но и функции, использующие соглашение cdecl.


Собственно, если речь идёт о компиляции проекта в EXE-файл — то всё вообще гладко и ничего делать не надо. Можно прямо сейчас компилировать такие программы.

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

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

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение Debugger » 04.02.2013 (Пн) 22:34

У меня возникает вопрос - почему многие фичи VB6, которые ты сейчас открываешь, не были должным образом задокументированы и предоставлены программисту?

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 04.02.2013 (Пн) 23:50

Хакер писал(а):В общем, я тут выяснил, что VB штатно от природы умеет компилировать программы, вызывающие не только stdcall-функции из внешних DLL, но и функции, использующие соглашение cdecl.

Хм.. А как он их различает?

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

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение Хакер » 04.02.2013 (Пн) 23:54

Debugger писал(а):У меня возникает вопрос - почему многие фичи VB6, которые ты сейчас открываешь, не были должным образом задокументированы и предоставлены программисту?

Много ли таких фич? Я могу вспомнить только эту.
Что ж документировать фичу, если она не работает. Ну или частично работает.

Qwertiy писал(а):Хм.. А как он их различает?

Для этого есть VB-шное ключевое слово CDecl, но в данном случае речь совсем не о нём :wink:
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение Хакер » 05.02.2013 (Вт) 0:08

В общем, VB вполне официально заявляет возможность поддерживать cdecl-функции.

Убедиться можно в этом хотя бы засунув в свой проект такую строчку:
Private Declare Sub Boombara CDecl Lib "foo.dll ()

Если вы попытаетесь вызвать такую функцию из проекта, то получите скорее ошибку «Bad DLL calling convention». И если вы нажмёте на кнопку Help в окошечке с этой ошибкой, то в хелпе по этой ошибке можно найти вполне официальное заявление:
MSDN98 об ошибке 49 писал(а):Bad DLL calling convention (Error 49)
Arguments passed to adynamic-link library (DLL) must exactly match those expected by the routine. Calling conventions deal with number, type, and order of arguments. This error has the following causes and solutions:

  • Your program is calling a routine in a DLL that's being passed the wrong type of arguments.
    Make sure all argument types agree with those specified in the declaration of the routine you are calling.

  • Your program is calling a routine in a DLL that's being passed the wrong number of arguments.
    Make sure you are passing the same number of arguments indicated in the declaration of the routine you are calling.

  • Your program is calling a routine in a DLL, but isn't using the StdCall calling convention.
    If the DLL routine expects argumentsby value, then make sure ByVal is specified for those arguments in the declaration for the routine.

  • Your Declare statement for a Windows DLL includes CDecl.
    For additional information, select the item in question and press F1.



Обратите внимание на последний пункт. В общем, об этом на форуме писали ещё давно — в 2004 году. И для меня это тоже далеко не новость была. Как видно из того топика, поддержка вызова CDecl-функций открыта только для Macintosh-версий VB/VBA (главным образом для маковского Офиса).

И вот как раз сегодня упомянув в одном ICQ-шном разговоре эту фичу, меня вдруг осенило:
— А в TLB-то мы тоже можем указывать calling convention наших функций (и методов)

Ну и был поставлен эксперимент.
Предположение было награждено удачным результатом!
Соглашение cdecl — поддерживается, и вызовы к нему совершенно правильно компилируются!

Заодно я выяснил, не поддерживается ли в довесок ещё и fastcall: оказалось, что нет, не поддерживается, и VB IDE честно и открыто на fastcall-ные функции ругается:

---------------------------
Microsoft Visual Basic
---------------------------
Compile error:

Calling convention not supported by Visual Basic
---------------------------
ОК Справка
---------------------------


Но на stdcall и cdecl не ругается, и отлично компилирует в Native-код. А вот в P-код отлично не компилирует — падает. А поскольку когда проект работает в режиме отладки, он компилируется именно в P-код, то отлаживать проекты с вызовом cdecl-функций невозможно.

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

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

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение Хакер » 05.02.2013 (Вт) 0:41

Вот, например, программа вот с таким кодом:
Код: Выделить всё
Private Sub Command1_Click()
    TheMagicIsHere inpName.Text, CLng(inpAge.Text)
End Sub

Public Sub TheMagicIsHere(ByRef sName As String, ByVal nAge As Long)
    Dim buffer As String: Buffer = Space(1000)
    wsprintf buffer, "Привет, %s, твой возраст — %d лет!", ByVal sName, ByVal nAge
    MsgBox buffer
End Sub


wsprintf (она же swprintf) — функция стандартной библиотеки языка Си, юникодная версия функции sprintf. Много функций сишного рантайма засунуты в ntdll и присутствуют на любой машине, и это как раз тот случай).

Компилируется на ура:
Изображение

И использует CRT-шную wsprintf прямо из ntdll (как я уже выше писал — она там есть):
Изображение

И работает на ура:
Изображение

Да можете сами поизучать:
wsprintf-test.zip
(3.31 Кб) Скачиваний: 491


Я уж было начал делать TLB-шку с объявлениями всех функций сишного рантайма (стандартной библиотеки Си), проживающих в NTDLL, таких как printf, scanf, isdigit, memcpy, strcpy, упомянутой в пресловутом топике qsort и им подобным. И тут такая досада — нельзя отлаживать (дело даже не доходит до вызова функций), ибо падает. Но, ещё раз, я постараюсь что-нибудь придумать.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение ALX_2002 » 17.04.2014 (Чт) 11:42

Хакер, доброго дня великому и ужасному. :wink: Очень интересует данная тема. Что-нибудь получилось в этом направлении ?

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

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение Хакер » 17.04.2014 (Чт) 11:43

ALX_2002 писал(а):Что-нибудь получилось в этом направлении ?

А что должно получиться? Фича раскрыта. Пользуйтесь.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение ALX_2002 » 17.04.2014 (Чт) 11:45

Хакер писал(а):И тут такая досада — нельзя отлаживать (дело даже не доходит до вызова функций), ибо падает. Но, ещё раз, я постараюсь что-нибудь придумать.


Так я собственно об этом. )

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

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение Хакер » 17.04.2014 (Чт) 11:50

Не занимался этим.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Оказывается VB6 поддерживат вызов cdecl-функций

Сообщение The trick » 03.02.2021 (Ср) 16:13

UA6527P


Вернуться в Мой блог

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

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

    TopList