Воскресенье, 19.05.2024, 03:36
Personal dimanche13 site
Главная | Регистрация | Вход Приветствую Вас Гость | RSS
Категории каталога
Мои статьи [22]
BlitzMax [17]
раздел содержит статьи относящиеся к языку программирования BlitzMax
SDL [9]
раздел содержит статьи на тему SDL
Code::Blocks [3]
в этом разделе рассказывается как прикрутить движок к интегрированной среде разработки(IDE) Code::Blocks
Форма входа
Поиск
Друзья сайта
Главная » Статьи » BlitzMax

BlitzMax и С. часть 1.

ВВЕДЕНИЕ.

Привет! Как вы наверное уже заметили, я использую БМакс для всех своих поделок(по другому и не назвать :) ) Пока еще не было задачи с которой бы он не справился. Для меня это простой и удобный инструмент для быстрого теста идей и алгоритмов пришедших мне на ум. Если вы его не используете, то спрашивается, что вы здесь вообще делаете? нафиг вам читать то, что написано ниже? Так вот, чем еще хорош БМакс, так это тем ,что его можно расширять функциями написанными на других языках. На данный момент БМакс поддерживает файлы: .c (C); .cpp (C++); .cxx (C++); .m (ObjectiveC); and .s (Assembler). Для компилирования этих файлов используются GNU Compiler tools или другими словами MinGW, бесплатные компиляторы этих языков (С/С++/ObjectiveC, а для ассемблера используется fasm). Конечно, их надо устанавливать отдельно, кроме fasm, в поставку БМакса они не входят, так как всего-лишь расширяют язык, но не являются его необходимой частью. Впрочем, если вы частенько меняете исходные коды самого БМакса( !!! о_О ??? ) или его С/С++ модулей, то вам будет необходимо их перекомпиливать, чтобы изменения внесенные вами возымели свое действие. Перекомпилирование модулей, достаточно тривиальная задача. Достаточно дать из ИДЕ команду ReBuild All Modules. Или если вы хотите перекомпилить какой-то конкретный модуль, то проще это сделать из командной строки. Зайдя в папку bin где лежит файл bmk.exe дать команду bmk makemods brl.appstab -эта команда перекомпилит модуль appstub. Причем, если код модуля содержит файлы написанные на С или С++, то в дело включится так же MinGW. Вернемся все же к теме нашего повествования. Объединить код написанный на разных языках вполне просто. Давайте начнем с самого простого. Простое с давних пор ассоциируется у меня с программой выводящей Hello World  на экран, так не будем нарушать традиций :)

ПРИВЕТ МИР! (1)

Итак будем печатать эту строку из С, но вызывая функцию из БМакса. Для этого нам необходимо создать файл test000.c содержащий самый простой код.

// файл test_000.c

#include <stdio.h> // для printf

void HelloWorld()
{
 printf("Hello World!");
}

Если приведенный код для вас как китайская грамота и вы не знаете С или С++, то к вам снова мой вопрос: что вы здесь делаете? Для тех кто в танке, я не буду учить программировать на этих языках, я лишь показываю как объединить их усилия. Программа на БМаксе:

' test_000.bmx

SuperStrict

Import "test_000.c"       ' импортируем наш файл написанный на С

Extern "C"    ' теперь объвим, что нам оттуда взять 
 Function HelloWorld()  ' а взять нам надо одну функцию, вы знаете какую :)
End Extern

HelloWorld()  ' теперь вызываем ее !!!

End ' зэ-энд - как говорят у нас в деревне

Если компиляция прошла успешно, то при запуске программы вы увидите строку "Hello world!". Если же ничего не скомпилировалось, то видимо MinGW не настроен у вас в системе должным образом. Самый простой способ проверить правильно ли у вас настроен Gcc это дать команду cmd /k gcc --version из Пуск->Выполнить, при этом вы увидите еще и установленную версию. У меня это "gcc (GCC) 3.4.5 ". Правда ведь ничего сложного?

ПРИВЕТ МИР! (2)

Напишем второй тест. Теперь из С будет возвращаться строка "Hello World!", а печатать ее будет БМакс. Подвох этой задачи в том, что в С/С++ нет такого понятия как "строка", соответственно нет и типа данных string - как в БМаксе. А что же тогда есть? Для С, строка - это просто массив символов идущих друг за другом и кончающихся нулевым терминатором (\0х00). Вот, к примеру, строка из пяти символов char mystring[5];. Чаще всеже обозначается как указатель типа char: char *mystring; 

// test_001.c

char* HelloWorld()  // возвращаем указатель на строку символов
{
 return "Hello World!";
}

Здесь для лучшей читаемости, можно ввести typedef константу:

typedef char* string; 

тогда код приобретет более наглядный и привычный для вас вид:

typedef char* string;

string HelloWorld()
{
 return "Hello World!";
}

Вот код программы на БМаксе

' test_001.bmx

SuperStrict

Import "test_001.c"

Extern "C"
 Function HelloWorld$z()
End Extern

Print HelloWorld()

End

Знаю, очень бросается в глаза название экспортируемой функции: HelloWorld$z, как вы знаете тип каждой переменной можно задавать двумя способами классическим a:float, b:int, c:double и присущим бэйсик языкам: a#, b%, c! . Так вот строковая переменная классически обозначается d:string, а по-другому d$. Но есть и еще одно обозначение строковой переменной $z - это таже самая строка ($), но на языке С. Еще раньше в своей статье о строках в БМаксе я говорил и подчеркивал тот факт, что здесь она состоит из набора short- двухбайтовых значений, в то время как в С строка это набор однобайтовых значений, так как тип char однобайтовый. Наша функция возвращает строку из С, поэтому ее возвращаемое значение $z. Уффф, думаю понятно. Конечно есть способ вернуть и указатель на однобайтовые значения, если в С это char*, то в БМаксе это Byte Ptr, тогда наша экспортируемая функция имела бы такой прототип:

Extern "C"
 Function HelloWorld:Byte Ptr()
End Extern

что ни в коем случаем не протеворечило бы действительности. (Кстати, тип byte обозначается еще и так "@", тогда тоже самое можно было бы написать по-другому HelloWorld@ Ptr().) Но не стоит забывать что для того чтобы распечатать данные на которые указывает указатель, все равно пришлось бы преобразовать их к С-строке. Вот так:

Print String.FromCString( HelloWorld() )

Исходники содержат 2 перечисленных способа загрузки под буквами a и b .

ПРИВЕТ МИР! (3)

Давайте все же поприветствуем мир и в третий раз. По старой русской традиции ;) На этот раз мы возвратим в БМакс строку понятную ему. И пусть он ее печатает. Но для начала, я хочу вам рассказать одну вещь. Так как БМакс был написан на С/С++ то соответственно все его типы должны быть описаны и доступны из языка С. Находятся они здесь: ..\mod\brl.mod\blitz.mod\blitz_types.h как видите все они очень предсказуемо называются, так например БМаксовский int - в исходниках это BBINT, type - это BBCLASS, string - BBSTRING, а любой объект Object - это BBOBJECT. Тогда чтобы их использовать достаточно прицепить файл blitz.h к нашему С-файлу. Ок, поехали, для начала БМ-код:

' test_002.bmx

SuperStrict

Import "test_002.c"

Extern "C"
 Function HelloWorld:String()
End Extern

Print HelloWorld()

End

Как видите функция HelloWorld возвращает теперь тип string, родной для БМакса. Но и нам из С - тогда тоже надо вернуть ее родной тип. Из файла blitz_types.h становится очевидным, что нам надо вернуть BBSTRING, но как переконвертировать в него строку? Ответ я нашел в файле blitz_string.h это делает функция BBString* bbStringFromCString( const char *p ); Теперь напишем нашу С-программу:

// test_002.c

#include <brl.mod/blitz.mod/blitz.h> '  цепляем описания типов и ф-ции 

BBSTRING HelloWorld()
{
 return bbStringFromCString("Hello World!");  // конвертируем в строку БМакса
}

Пробуем, все работает! 

http://dimanche.ucoz.ru/C_tests.zip



Категория: BlitzMax | Добавил: dimanche (10.01.2009)
Просмотров: 1938 | Комментарии: 3 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Имя *:
Email *:
Код *:
Copyright MyCorp © 2024