Взаимодействие с C
 
ВНИМАНИЕ! Придется сделать некоторую проверку орфографии, проверку текста, кода и имен файлов.

Предисловие

Это крошечный учебник о том, как написать простую библиотеку в C и затем использовать ее в FreeBASIC. Учебник можно исследовать без особых знаний о C или FreeBASIC. После выполнения этого учебника вы сможете скомпилировать статические и динамически компонуемые библиотеки C. Перевести необходимые заголовочные файлы для FreeBASIC и понять, как использовать библиотеки в проекте FreeBASIC.


Что такое библиотека


Предпосылка

Данное руководство было написано и протестировано с FreeBASIC 0.16b и последней текущей версией mingw32 на тот момент. Как примечание Dev-CPP использует компилятор mingw32. Вы также можете получить Code :: Blocks с mingw32 .


Формальное описание задачи

Чтобы продемонстрировать использование C-библиотеки в FreeBASIC , нам нужно создать простую библиотеку с несколькими функциями. Создать тестовый файл в C, чтобы продемонстрировать, что наша библиотека работает как задумано. После мы должны перевести файл заголовка библиотеки в заголовочный файл FreeBASIC (* .bi) и наконец создать тестовый проект в FreeBASIC, с использованием библиотеки.

Создание файлов

Поэтому наш список файлов будет выглядеть следующим образом:
myClib.c: C файл реализации нашей библиотеки.
myClib.h: C заголовочный файл, описывающий интерфейс библиотеки.
myClibCTest.c: C файл реализации нашей тестовой программы в C.
myClib.bi: FreeBASIC заголовочный файл. Транслируется из myClib.h.
myClibFBTest.bas: FreeBASIC тестовый файл
make.cmd: Пример скрипта оболочки для компиляции библиотеки и тестирования файлов.


C файл станет статической библиотекой. myClib.c
(C)
/* Функция сложения двух целых чисел с возвращением результата */
#include "myClib.h"
int SampleAddInt(int i1, int i2)
{
	return i1 + i2;
}

/* Функция ничего не делает ;) */
void SampleFunction1()
{
	/* вставка кода сюда */

}

/* Функция, возвращающая ноль */
int SampleFunction2()
{
	/* вставка кода сюда */

	return 0;
}
Заголовочный файл myClib.h
(C)
int  SampleAddInt(int i1, int i2);
void SampleFunction1();
int  SampleFunction2();

Тестовый проект С для проверки. myClibCTest.c:
(C)
#include 
#include 
#include "myClib.h"
int main(int argc, char *argv[])
{
  printf("SampleAddInt(5, 5):=%d\n", SampleAddInt(5, 5));
  system("PAUSE");	
  return 0;
}


Трансляция заголовочного файла C в заголовочный файл FreeBASIC
myClib.bi: Для взаимодействия со статической библиотекой и автоматического включения ее(#inclib "myClib" ) .
''заголовочный файл для libmyClib.a
#ifndef __myClib_bi__
#define __myClib_bi__
#inclib "myClib"

Declare Function SampleAddInt cdecl Alias "SampleAddInt" (ByVal i1 As Integer, ByVal i2 As Integer) As Integer
Declare Sub SampleFunction1 cdecl Alias "SampleFunction1" ()
Declare Function SampleFunction2 cdecl Alias "SampleFunction2" () As Integer
#endif



И, наконец, FreeBASIC файл, использующий библиотеку
myClibFBTest.bas:
''Тестирование функций в myClib.bi
#include "myClib.bi"
''
Print "SampleAddInt(10, 10):=", SampleAddInt(10, 10)
'' Just a dumy call
SampleFunction1()
''
Print "SampleFunction2():=", SampleFunction2()



Make файл: make.cmd
Я создал пакетный файл для компиляции всех файлов. Включая пример C с использованием статической библиотеки. Обратите внимание на конфигурацию линий в верхней части, которые должен быть изменены в комплекте установки.
(cmd)
@REM TODO: Set PATH's for this session.
SET PATH=C:\mingw32\bin;c:\mingw32\mingw32\bin
SET MINGW_INCLUDE="C:/MinGW32/include"
SET MINGW_LIB="C:/MinGW32/lib"

@REM
@REM fbc testing SET fbc="C:\portableapps\FreeBASIC\fbc.exe"
SET fbc="C:\FreeBasic16b\fbc.exe"
@echo *** Verify pat's to compilers
@pause
@echo off

@REM
@REM Remove old files
DEL /F *.o  *.a myClibFBTest.exe

@REM
@REM Create static lib from c source
gcc.exe -c myClib.c -o myClib.o -I%MINGW_INCLUDE%

@REM
@REM ar: creating libstatictest.a
ar r libmyClib.a myClib.o 

@REM
@REM No nead for ranlib anymore? ar is supposed to take care of it 
ranlib libmyClib.a


@REM
@REM Create a test with a C file

gcc.exe -c myClibCTest.c -o myClibCTest.o -I%MINGW_INCLUDE%
gcc.exe myClibCTest.o -o "myClibCTest.exe" -L%MINGW_LIB% libmyClib.a

echo =====================================
echo RUnning C sample
echo =====================================
myClibCTest.exe

echo =====================================
echo Creating FreeBASIC sample
echo =====================================
REM I thought this explicit reference is unnecessary as I use #inclib
SET fbcop= -I myClib
SET fbcfl="myClibFBTest.bas" 
%fbc% %fbcop% %fbcfl%
echo =====================================
echo RUnning FreeBASIC sample
echo =====================================
myClibFBTest.exe
@pause


Встречающиеся ошибки и их решения

undefined reference to (необъявленная ссылка на)
Пытаясь связать статические библиотеки C без использования cdecl alias "functionname" в файле заголовка FreeBASIC приводит к ошибкам, типа таких.
(cmd)
C:\code>"C:\FreeBasic16b\fbc.exe"     "myClibFBTest.bas"
myClibFBTest.o:fake:(.text+0x3d): undefined reference to `SAMPLEADDINT@8'
myClibFBTest.o:fake:(.text+0x4a): undefined reference to `SAMPLEFUNCTION1@0'
myClibFBTest.o:fake:(.text+0x67): undefined reference to `SAMPLEFUNCTION2@0'
Press any key to continue . . .

Для решения этой проблемы вам придется найти объявление функции в файле *.bi, которое выглядит как это:
Declare Function SampleAddInt(ByVal i1 As Integer, ByVal i2 As Integer) As Integer

И изменить его на что-то вроде этого:
Declare Function SampleAddInt cdecl Alias "SampleAddInt" (ByVal i1 As Integer, ByVal i2 As Integer) As Integer



Приложение A: ссылки

Основой для этого учебника является несколько веток в форуме.
Некоторые интересные ссылки, содержащие информацию по подключению библиотеки, созданной в FreeBASIC и используемые в других языках или наоборот.

Как скомпилировать проект C как статическую библиотеку для включения ..