Экспортирование и импортирование функций (Extern - End Extern)

 

Подключение библиотек(статических или динамических) , особенно написанных на других языках, проще всего проводить с помощью блока Extern-End Extern. Однако тут есть свои правила. Библиотеки пишутся на разных языках и они используют разные модели импорта функций. Так из известных мне:

  • "C"   (соглашение cdecl) - совместимое с языком С
  • "C++" (соглашение cdecl) -  совместимое с С++  (g++-4.x)
  • "Windows" (соглашение stdcall) - по умолчанию в FreeBasic с суффиксом @N)
  • "Windows-MS" (соглашение stdcall без добавления суффикса @N)

Когда вы например создаете библиотеку в FreeBasic, к ее функциям автоматически приписываются по соглашению "Windows" знак @ и число, которое показывает общее кол-во байт, используемых функцией:

func@8

Вы это можете проверить, создав библиотеку и открыв ее в Hex редакторе, например в этом  Найдите поиском имя вашей функции, и вы убедитесь в этом.

Hex

Очень часто это помогает(не в полной мере конечно) другим разработчикам использовать Dll , если нет никаких других данных об библиотеке. В данном случае, хотя бы известно кол-во байт, занимаемых параметрами. Опытный реверсер сумеет найти недостающие звенья.
Если вы будете использовать другое соглашение для своей библиотеки, то ваши функции будут выглядеть без суффиксов.

 Пример использования другого соглашения:

Extern "C"
Function AA() As Integer Export
    Return 100
End Function
End Extern

Скомпилируйте этот пример как статическую или динамическую библиотеку обычным образом. Далее в этой же папке создайте исходный файл с любым именем и в нем:

#Inclib "uu"

Extern "C"
  Declare Function AA() As Integer
End Extern
? AA
Sleep


В принципе я думаю ничего сложного. Загляните теперь в Hex редактор и поищите там нашу функцию. Как видите теперь нет никаких символов около нашей функции. В примере только одна функция, но можно использовать столько , сколько нужно.

И для общего развития.  Можете просто прочитать, можете установить компилятор С и попробовать ниже описанные примеры, дело ваше  :)

Давайте создадим простую библиотеку с помощью языка С и после вызовем ее с помощью блока Extern end Extern в FreeBasic.

Чтобы это было удобно, можете установить любую из сред: CodeBlocks или DEV-C++ Они идут уже со встроенным компилятором. Так что настраивать ничего не придется. Я покажу на примере CodeBlocks.

Запускаем редактор и жмем Create new project:

CodeBlocks

В открывшемся окне находим пункт для создания статической библиотеки и нажимаем Go:

CodeBlocks

Далее вводим имя нашей библиотеки, я назвал QQQ и место сохранения и нажимаем Next

CodeBlocks

В следующем окне ничего не нужно менять, просто жмем Finish. Открывается сам редактор. Находим слева в дереве наш единственный файл main и в нем уже для нас припасен шаблон из трех функций. Если в вашей версии нет такого, то напишите одну из функций, которая носит название SampleAddInt (сложение двух чисел), остальные можно не писать.

CodeBlocks

Далее просто компилируем:

CodeBlocks

Теперь у нас в папке куда вы сохранили проект появилась библиотека libQQQ.a
Ничего не напоминает? Да действительно синтаксис записи имени и расширения полностью соответствует синтаксису записи обычных статических библиотек в FreeBasic. Давайте рядом с файлом (в этой же папке) создадим исходный файл FreeBasic с любым именем и расширенем .BAS

И в нем напишем следующее:

#Inclib "QQQ"

Extern "C"
  Declare Function SampleAddInt(As Long , As Long) As Long
End Extern
? SampleAddInt(100,200)
Sleep


Примечание: Я использовал для декларации тип Long потому , что в СИ тип int эквивалентен типу long в FreeBasic. Как видите, мы работаем в FreeBasic с библиотекой, написанной на языке С как со своей. В будующем, решая какие-то серьезные задачи, вы часто будете использовать библиотеки, написанные на языке С , поскольку большинство качественных библиотек написано именно на этом языке, да и использовать их как вы заметили довольно просто. На этом главу о модульном программировании я завершаю, не забудьте удалить тот проект (QQQ) , который мы создали, не к чему лишний мусор на компьютере  :). Но в завершении обобщенно хочется добавить:

Использовать модульное программирование можно, а  иногда и нужно не только для библиотек, но и для исполняемых файлов. Делить на модули желательно такие проекты, которые предполагаются быть объемными. Не к чему, делить на модули код из 10 - 200 строчек, зачастую это только затрудняет отладку приложения. Во всем нужна сбалансированность и в первую очередь простота.

Всего доброго!

содержание | назад | вперед