├── .gitignore ├── LICENSE.md ├── README.md ├── arrfun ├── arrfun.c ├── arrfun.h ├── main3.c ├── outc ├── prog3.pas └── unit3.pas ├── docs ├── CinFreePascal.pdf ├── Creating Pascal bindings for C (v1.0).pdf ├── Creating Pascal bindings for C.tex └── README.md ├── fibonacci ├── fibDyn.pas ├── fibDynSystemError.png ├── fibStat.pas ├── fibonacci.c ├── fibonacci.h ├── main.c ├── ulibfibDyn.pas └── ulibfibStat.pas ├── hello ├── hello.c ├── hello.h ├── main2.c ├── prog2.pas └── unit2.pas └── sum ├── main1.c ├── prog1.pas ├── sum.c ├── sum.h └── unit1.pas /.gitignore: -------------------------------------------------------------------------------- 1 | # C GNU libs 2 | *.o 3 | *.so 4 | *.a 5 | 6 | # Pascal 7 | *.ppu 8 | *.res 9 | 10 | # LaTeX 11 | *.toc 12 | *.log 13 | *.gz 14 | *.aux 15 | *.out 16 | 17 | # Other 18 | *.exe 19 | *.txt 20 | 21 | # Directories 22 | .vscode 23 | backup/ 24 | temp/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 William Hunter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to use C code in Pascal 2 | Examples that shows how to use libraries that were created in C in Pascal, specifically Free Pascal (or FPC). 3 | In other words: how to use C libraries from Pascal, or linking to C libraries from Pascal. 4 | 5 | ## Documentation 6 | See the [docs](https://github.com/williamhunter/pascal-bindings-for-c/tree/master/docs) folder. 7 | -------------------------------------------------------------------------------- /arrfun/arrfun.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: arrfun.c 3 | * 4 | */ 5 | 6 | void multelem(double u[], double v[], double w[], int len_w) 7 | // Multiply arguments element-wise; vectors must be same length 8 | { 9 | int i; 10 | 11 | for (i = 0; i < len_w; i++) 12 | { 13 | w[i] = u[i] * v[i]; 14 | } 15 | } 16 | 17 | double sumelem(double v[], int len_v) 18 | // Sum of elements 19 | { 20 | double ans = v[0]; 21 | int i; 22 | 23 | for (i = 1; i < len_v; i++) 24 | { 25 | ans = ans + v[i]; 26 | } 27 | 28 | return ans; 29 | } 30 | -------------------------------------------------------------------------------- /arrfun/arrfun.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: arrfun.h 3 | * 4 | */ 5 | 6 | #ifndef ARRFUN_H 7 | #define ARRFUN_H 8 | 9 | // Function prototype(s) 10 | 11 | void multelem(double u[], double v[], double w[], int len_w); 12 | // Multiply arguments element-wise; vectors must be same length 13 | 14 | double sumelem(double v[], int len_v); 15 | // Sum of elements 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /arrfun/main3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: main3.c 3 | * 4 | */ 5 | 6 | #include 7 | #include 8 | #include "arrfun.h" 9 | 10 | int main(void) 11 | { 12 | int i; 13 | 14 | // two vectors 15 | double a[] = {1,2,3,4,5}; 16 | double b[] = {6,2,4,7,5}; 17 | double c[] = {0,0,0,0,0}; 18 | 19 | // determine length of vectors 20 | int veclen = sizeof(a) / sizeof(double); 21 | 22 | // multiply vectors element-wise 23 | multelem(a, b, c, veclen); 24 | 25 | // print result 1 26 | printf("From C: The multiplied elements are:\n"); 27 | for (i = 0; i < veclen; i++) 28 | { 29 | printf("Item %d: %f\n", i, c[i]); 30 | } 31 | 32 | // print result 2 33 | printf("From C: The sum of the elements is:\n"); 34 | printf("Sum: %f\n", sumelem(c, veclen)); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /arrfun/outc: -------------------------------------------------------------------------------- 1 | From C: The multiplied elements are: 2 | Item 0: 6.000000 3 | Item 1: 4.000000 4 | Item 2: 12.000000 5 | Item 3: 28.000000 6 | Item 4: 25.000000 7 | From C: The sum of the elements is: 8 | Sum: 75.000000 9 | -------------------------------------------------------------------------------- /arrfun/prog3.pas: -------------------------------------------------------------------------------- 1 | program prog3; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | unit3; 7 | 8 | var 9 | a: array[0..4] of double = (1, 0.5, 1/3, 0.25, 0.2); 10 | b: array[0..4] of double = (5, 3.2, 8.5, 4.05, 1.4); 11 | c: array[0..4] of double = (0, 0, 0, 0, 0); 12 | veclen: integer = length(a); 13 | i: integer; 14 | ans : double; 15 | 16 | begin 17 | writeln('From Pascal: The multiplied elements are:'); 18 | multelem(a, b, c, veclen); 19 | for i := 0 to veclen - 1 do 20 | writeln('Item ', i:1, ': ', c[i]:1:2); 21 | 22 | writeln(''); 23 | writeln('From Pascal: The sum of the elements is:'); 24 | ans := sumelem(b, veclen); 25 | writeln('Sum :', ans:5:1); 26 | end. 27 | -------------------------------------------------------------------------------- /arrfun/unit3.pas: -------------------------------------------------------------------------------- 1 | unit unit3; 2 | 3 | {$link arrfun.o} 4 | 5 | interface 6 | // leave this empty 7 | 8 | uses ctypes; 9 | 10 | procedure multelem(u, v, w:pcdouble; len_w:cint32); cdecl; external; 11 | // multiply arguments element-wise; vectors must be same length 12 | 13 | function sumelem(v:pcdouble; len_v:cint32): cdouble; cdecl; external; 14 | // sum of elements 15 | 16 | implementation 17 | // leave this empty 18 | 19 | end. 20 | -------------------------------------------------------------------------------- /docs/CinFreePascal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamhunter/pascal-bindings-for-c/32546595442182afc187f2afea04fc813dde5853/docs/CinFreePascal.pdf -------------------------------------------------------------------------------- /docs/Creating Pascal bindings for C (v1.0).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamhunter/pascal-bindings-for-c/32546595442182afc187f2afea04fc813dde5853/docs/Creating Pascal bindings for C (v1.0).pdf -------------------------------------------------------------------------------- /docs/Creating Pascal bindings for C.tex: -------------------------------------------------------------------------------- 1 | \documentclass[10pt,a4paper]{article} 2 | 3 | % USE NORMAL DATES 4 | \usepackage{datetime} 5 | 6 | % GRAPHICS 7 | %\usepackage{graphicx} 8 | 9 | % FONTS for pdfLaTeX 10 | %\usepackage[charter]{mathdesign} 11 | %\usepackage[scaled=0.86]{berasans} % sans-serif font 12 | %\usepackage{inconsolata} % typewriter 13 | %\usepackage[T1]{fontenc} 14 | 15 | % FONTS for XeLaTeX 16 | \usepackage{fontspec} 17 | \setmainfont[Scale=1.1]{Cambria} 18 | \setsansfont{Tahoma} 19 | \setmonofont{Consolas} 20 | %\usepackage{unicode-math} 21 | %\setmathfont{Cambria Math} 22 | 23 | % SECTION FONT STYLE 24 | \usepackage{sectsty} 25 | \allsectionsfont{\sffamily} % make sections sans-serif 26 | 27 | % PAGE BORDERS 28 | \usepackage[top=40mm,bottom=20mm,left=25mm,right=25mm]{geometry} 29 | 30 | % PARAGRAPH BEHAVIOUR 31 | \setlength{\parskip}{1em} 32 | \setlength{\parindent}{0pt} 33 | 34 | % CODE FORMATTING 35 | \usepackage{listings} 36 | \usepackage[usenames,dvipsnames]{color} 37 | \definecolor{LightGray}{rgb}{0.95,0.95,0.95} 38 | 39 | \lstdefinestyle{myC}{ 40 | belowcaptionskip=1\baselineskip, 41 | breaklines=true, 42 | backgroundcolor=\color{LightGray}, 43 | frame=none, 44 | numbers=none, 45 | numbersep=10pt, 46 | numberstyle=\color{Gray}, 47 | xleftmargin=10pt, 48 | language=C, 49 | showstringspaces=false, 50 | basicstyle=\small\ttfamily, 51 | keywordstyle=\bfseries\color{Blue}, 52 | commentstyle=\itshape\color{ForestGreen}, 53 | identifierstyle=\color{Fuchsia}, 54 | stringstyle=\color{Sepia}, 55 | } 56 | 57 | \lstdefinestyle{myPascal}{ 58 | belowcaptionskip=1\baselineskip, 59 | breaklines=true, 60 | backgroundcolor=\color{LightGray}, 61 | frame=none, 62 | numbers=none, 63 | numbersep=10pt, 64 | tabsize=2, 65 | numberstyle=\color{Gray}, 66 | xleftmargin=10pt, 67 | language=Pascal, 68 | showstringspaces=false, 69 | basicstyle=\small\ttfamily, 70 | comment=[l]{//}, 71 | keywordstyle=\bfseries\color{Blue}, 72 | commentstyle=\itshape\color{ForestGreen}, 73 | identifierstyle=\color{Blue}, 74 | stringstyle=\color{Sepia}, 75 | } 76 | 77 | \lstdefinestyle{myBash}{ 78 | breaklines=false, 79 | backgroundcolor=\color{White}, 80 | frame=none, 81 | numbers=none, 82 | numbersep=10pt, 83 | xleftmargin=10pt, 84 | language=Bash, 85 | showstringspaces=false, 86 | basicstyle=\small\ttfamily, 87 | keywordstyle=\bfseries, 88 | commentstyle=\itshape, 89 | identifierstyle=\color{Magenta}, 90 | stringstyle=\color{Sepia}, 91 | } 92 | 93 | 94 | % TITLE PAGE 95 | \title{Creating Pascal bindings for C\\ 96 | \vspace{0.5em} 97 | \normalsize v1.0} 98 | \author{W Hunter} 99 | \newdateformat{mydate}{\monthname[\THEMONTH] \THEYEAR} 100 | \date{\mydate\today} 101 | 102 | % HYPERLINKS 103 | \usepackage[pdfauthor={William Hunter}, 104 | colorlinks=true, 105 | linkcolor=BlueViolet]{hyperref} 106 | 107 | % NEW COMMANDS 108 | \newcommand{\mytext}[1]{\textcolor{ForestGreen}{\texttt{#1}}} 109 | 110 | 111 | % BEGIN DOCUMENT 112 | \begin{document} 113 | \maketitle 114 | \tableofcontents 115 | \clearpage 116 | 117 | \section{Purpose of document} 118 | The purpose of this document is to show how to use C libraries from Object 119 | Pascal, more specifically using Free Pascal (FPC). It is inspired by 120 | \cite{cinfree}, but showing a more up to date approach as per 121 | the \textit{Free Pascal Programmer's Guide} 122 | \mytext{http://www.freepascal.org/docs-html/prog/progse28.html}, 123 | and with help from `Thaddy' on the FPC forum. 124 | 125 | I suggest you read everything in this document (that means the whole 126 | document), including the source files, 127 | because I've also put explanations and hints in them. 128 | 129 | In all the examples that follow I'll first show the C code and how to compile it, 130 | and then the same for the Pascal code. Each example has three C source code files: a Header, 131 | a Module and finally the C program itself.\footnote{If you 132 | want to read up about C programming, have a look at the \textit{Deitel} books on C 133 | programming, I've also found \textit{C for Linux Programming} (by Castro Lopo, Aitken and 134 | Jones) to be a good book, especially if you're 135 | going to be using \textit{gcc}.} 136 | 137 | If you're not familiar with C you might wonder why one would go through all the 138 | trouble of creating three separate files, especially for something as trivial 139 | as adding two numbers? 140 | 141 | One reason is to keep the function definition separate from the actual C program, this way 142 | you can have many different C programs that can use the same functions (and possibly other 143 | things). If a function is defined in a C program and you wanted to use it in another 144 | program, you'd have to rewrite (or copy) that piece of code every time. But you probably 145 | know this. 146 | 147 | Another reason, and relevant in the context of this document, is that C libraries generally 148 | take this form, namely, they consist of a Header file 149 | and the Module; the examples in this document tries to mimic that. 150 | 151 | The approach is one of the following methods: 152 | \begin{enumerate} 153 | \item Compile the C module into an object file (*.o file) and link to the object file, or 154 | \item Create a library (static) from the object files and then link 155 | to the library or 156 | \item Create a library (shared) from the object files and then link 157 | to the library. 158 | \end{enumerate} 159 | 160 | I'll show how to do all three methods. 161 | 162 | \section{Prerequisites} 163 | You need to have a fairly good knowledge of the C language, and of course of 164 | Object Pascal too. Where I refer to Pascal in this document, it also means 165 | Object Pascal, although in the context of this document it makes little or no difference. 166 | 167 | If you spot an error or a typo or an improvement (I'm a hobbyist programmer), 168 | please let me know. You can mail me at \mytext{whunter.za+pbc@NOSPAMgmail.com} 169 | (delete the \mytext{NOSPAM} bit). 170 | 171 | \section{Development environments} 172 | \subsection{Windows 7/8.1/10} 173 | You'll need the following two compilers: 174 | \begin{itemize} 175 | \item FPC (Free Pascal Compiler) -- \mytext{http://www.freepascal.org/} 176 | \item GCC (MinGW GNU C Compiler) -- \mytext{http://www.mingw.org/} 177 | \end{itemize} 178 | 179 | Setting up MinGW (Minimalist GNU for Windows) on Windows can be painful (to say the least). 180 | If on 64-bit, I suggest you download \mytext{mingw-w64-install.exe} instead of 181 | \mytext{mingw-get-setup.exe}, the latter didn't work for me on \textit{Windows 10}. 182 | 183 | \subsection{Linux (Ubuntu)} 184 | All the code in this document was compiled and ran successfully in \textit{Ubuntu 14.04 185 | LTS 64-bit}, using FPC and GCC. The approach on Linux is a little different for Shared 186 | Objects (Dynamic Libraries) compared to Windows, in particular, 187 | you may have to do the following or a variant thereof: 188 | 189 | The C modules must be 190 | compiled as ``position-independent code'' using gcc's `fPIC' flag, for example: 191 | 192 | \mytext{gcc -c -fPIC -o sum.o sum.c}\\ 193 | \mytext{gcc -c -fPIC -o hello.o hello.c}\\ 194 | 195 | Create a Shared Object\\ 196 | \mytext{gcc -shared -fPIC sum.o hello.o -o liball.so}\\ 197 | 198 | Set permissions (if required)\\ 199 | \mytext{chmod 755 liball.so} 200 | 201 | Copy lib to a standard location\\ 202 | \mytext{sudo cp liball.so /usr/local/lib/} 203 | 204 | Copy headers to a standard location\\ 205 | \mytext{sudo cp sum.h /usr/local/include/} 206 | \mytext{sudo cp hello.h /usr/local/include/} 207 | 208 | We need to copy the header files to the same location as the library 209 | so that function prototypes are available to someone 210 | who wants to link to the library, unless the prototypes are known otherwise. 211 | 212 | Ask loader to update cache\\ 213 | \mytext{sudo ldconfig} 214 | 215 | \clearpage 216 | \subsection{Compiler versions} 217 | The code examples in this document was last tested and worked on 218 | \textit{Windows 10 64-bit}, using 219 | \begin{itemize} 220 | \item \mytext{Free Pascal Compiler version 3.0.0 [2015/11/16] for i386} 221 | \item \mytext{gcc (x86\_64-win32-seh, Built by MinGW-W64 project) 6.1.0} 222 | \end{itemize} 223 | 224 | \subsection{Conventions} 225 | Both Pascal programs and units uses the `pas' file extension. 226 | If using the \textit{Lazarus IDE} to compile your files, you may want to use `lpr' for your 227 | Pascal source files (but apparently not for units). 228 | 229 | Static Libraries uses the `a' file extension (referring to the fact that 230 | they're merely archives). 231 | 232 | Shared Objects (*.so) and Dynamic Libraries (*.dll) refer to the same thing, although I 233 | read somewhere that it's not a bad idea to keep the `so' extension on Windows machines 234 | too if using \textit{gcc}. That way users know that the library was probably compiled using 235 | \textit{MinGW} tools. 236 | 237 | You should know that Pascal code is not case sensitive, but C is, so keep this in 238 | mind when linking to external code, since your function prototypes have to 239 | be \textit{identical}. 240 | \clearpage 241 | 242 | \section{Linking to Object files} 243 | \subsection{The sum of two numbers} 244 | A trivial example showing how to calculate the sum of two integer numbers and print the result to standard output. 245 | 246 | \subsubsection{C source files} 247 | \lstset{style=myC} 248 | \subsubsection*{Header file 'sum.h'} 249 | This really just contains the function prototype, the rest is a C ``include guard'' (see for example \newline 250 | \url{http://en.wikipedia.org/wiki/Include\_guard)}) 251 | 252 | \lstinputlisting{../sum/sum.h} 253 | 254 | \subsubsection*{Module 'sum.c'} 255 | This is where the actual function's workings are defined, the function 256 | needs to correspond to the prototype in the Header file. 257 | \lstinputlisting{../sum/sum.c} 258 | 259 | \newpage 260 | \subsubsection*{Program 'main1.c'} 261 | Note that in the program we only include the Header file, and then simply call the function. We don't actually need to know how the function is implemented, we just need to know what the function definition looks like (by inspecting the Header file) so that we can use it. 262 | 263 | \lstinputlisting{../sum/main1.c} 264 | 265 | \subsubsection*{Compiling the C code} 266 | First create an object-code file from the C module; in a terminal (for example, \mytext{ConsoleZ} on \mytext{Windows}) type: 267 | 268 | \lstset{style=myBash} 269 | \begin{lstlisting} 270 | gcc -c sum.c 271 | \end{lstlisting} 272 | 273 | This should produce an object-code file \mytext{sum.o}. Now create a 274 | program called \mytext{main1.exe} by compiling and linking the 275 | object-code file and creating an executable: 276 | 277 | \lstset{style=myBash} 278 | \begin{lstlisting} 279 | gcc sum.o main1.c -o main1.exe 280 | \end{lstlisting} 281 | 282 | This should produce a file \mytext{main1.exe} (the 'exe' extension is only required on \mytext{Windows} machines). If you run the program 283 | (by typing its name in the terminal), you should get: 284 | 285 | \lstset{style=myBash} 286 | \begin{lstlisting} 287 | From C: The sum of 17 and 19 is 36 288 | \end{lstlisting} 289 | That just proves that the C code compiled and works as expected, which is 290 | obviously important. 291 | \clearpage 292 | 293 | 294 | \subsubsection{Pascal source files} 295 | Two files are required, namely a Pascal unit and the Pascal program. 296 | \lstset{style=myPascal} 297 | 298 | \subsubsection*{Unit 'unit1.pas'} 299 | We link to the C object file via the following Pascal unit. 300 | \lstinputlisting{../sum/unit1.pas} 301 | 302 | \subsubsection*{Program 'prog1.pas'} 303 | \lstinputlisting{../sum/prog1.pas} 304 | 305 | \textbf{NOTE:-} Nowhere in the above Pascal code did we define how to add two integers (since that would be pointless as it's already defined in the C code). 306 | \clearpage 307 | 308 | \subsubsection*{Compiling the Pascal code} 309 | We can now call the ``C generated'' \mytext{sum.o} object file from Pascal code. As you can see from the Pascal code above, the \mytext{sum} function isn't defined anywhere \textbf{except} in the C source code. And that's the whole idea, the intention is to use the ``C generated'' object-file from Pascal and not having to define (write the code for) the function again because it's already been done in C. 310 | 311 | Compile the Pascal program (output the file as \mytext{prog1.exe}, \mytext{fpc} will compile and link the files): 312 | 313 | \mytext{fpc prog1.pas -oprog1.exe} 314 | 315 | If you're on a 64-bit machine, you may have to type this instead (\textbf{this is 316 | true for the rest of the examples too}): 317 | 318 | \mytext{fpc -Px86\_64 prog1.pas -oprog1.exe} 319 | 320 | This should produce a file \mytext{prog1.exe}. If you run the program (by typing its name in the terminal), you will get 321 | 322 | \mytext{From Pascal: The sum of 12 and 51 is 63}. 323 | 324 | \textbf{NOTE:-} Since we've passed different values (12 and 51) to the \mytext{sum} function in the Pascal code, we obviously expect a different answer. 325 | \clearpage 326 | 327 | 328 | \subsection{Printing to screen} 329 | A slightly more complicated example showing how to print to standard output. 330 | 331 | For this example to work I had to link to \mytext{libmsvcrt.a} in my MinGW 332 | directory (just search for it). I just copied the library file to the same 333 | directory as my source files. 334 | 335 | \subsubsection{C source files} 336 | \lstset{style=myC} 337 | 338 | \subsubsection*{Header file 'hello.h'} 339 | \lstinputlisting{../hello/hello.h} 340 | 341 | \subsubsection*{Module 'hello.c'} 342 | \lstinputlisting{../hello/hello.c} 343 | 344 | \newpage 345 | \subsubsection*{Program 'main2.c'} 346 | \lstinputlisting{../hello/main2.c} 347 | 348 | \subsubsection*{Compiling the C code} 349 | As before, first create an object-code file from the C module; in a terminal type: 350 | 351 | \lstset{style=myBash} 352 | \begin{lstlisting} 353 | gcc -c hello.c 354 | \end{lstlisting} 355 | 356 | This should produce an object-code file \mytext{hello.o}. Now create a 357 | program called \mytext{main2.exe} by compiling and linking the 358 | object-code file and creating an executable: 359 | 360 | \lstset{style=myBash} 361 | \begin{lstlisting} 362 | gcc main2.c hello.o -o main2.exe 363 | \end{lstlisting} 364 | 365 | This should produce a file \mytext{main2.exe}. If you run the program (by typing its name in a terminal), you will get: 366 | 367 | \lstset{style=myBash} 368 | \begin{lstlisting} 369 | From C: 370 | Hello, World! 371 | Hello John Smith 372 | \end{lstlisting} 373 | \clearpage 374 | 375 | 376 | \subsubsection{Pascal source files} 377 | \lstset{style=myPascal} 378 | 379 | \subsubsection*{Unit 'unit2.pas'} 380 | We link to the C object file via the following Pascal unit. 381 | \lstinputlisting{../hello/unit2.pas} 382 | 383 | \subsubsection*{Program 'prog2.pas'} 384 | \lstinputlisting{../hello/prog2.pas} 385 | 386 | \newpage 387 | \subsubsection*{Compiling the Pascal code} 388 | Compile the Pascal program (output the file as \mytext{prog2.exe}): 389 | 390 | \mytext{fpc -Px86\_64 prog2.pas -oprog2.exe} 391 | 392 | This should produce a file \mytext{prog2.exe}. If you run the program (by typing its name in the terminal), you will get 393 | 394 | \lstset{style=myBash} 395 | \begin{lstlisting} 396 | From Pascal, calling C functions: 397 | Hello, World! 398 | Hello Joe Public 399 | \end{lstlisting} 400 | \clearpage 401 | 402 | \subsection{Simple array functions}\label{arrfun} 403 | An example showing how to work with 1-d arrays (vectors)using 404 | \textbf{fun}ctions that operate on \textbf{arr}ays. 405 | \subsubsection{C source files} 406 | \lstset{style=myC} 407 | 408 | \subsubsection*{Header file 'arrfun.h'} 409 | \lstinputlisting{../arrfun/arrfun.h} 410 | 411 | \subsubsection*{Module 'arrfun.c'} 412 | \lstinputlisting{../arrfun/arrfun.c} 413 | 414 | \subsubsection*{Program 'main3.c'} 415 | \lstinputlisting{../arrfun/main3.c} 416 | 417 | \clearpage 418 | \subsubsection*{Compiling the C code} 419 | As before, first create an object-code file from the C module; in a terminal type: 420 | 421 | \lstset{style=myBash} 422 | \begin{lstlisting} 423 | gcc -c arrfun.c 424 | \end{lstlisting} 425 | 426 | This should produce an object-code file \mytext{arrfun.o}. Now create a 427 | program called \mytext{main3.exe} by compiling and linking the 428 | object-code file and creating an executable: 429 | 430 | \lstset{style=myBash} 431 | \begin{lstlisting} 432 | gcc main3.c arrfun.o -o main3.exe 433 | \end{lstlisting} 434 | 435 | This should produce a file \mytext{main3.exe}. If you run the program (by typing its name in a terminal), you will get: 436 | 437 | \lstset{style=myBash} 438 | \begin{lstlisting} 439 | From C: The multiplied elements are: 440 | Item 0: 6.000000 441 | Item 1: 4.000000 442 | Item 2: 12.000000 443 | Item 3: 28.000000 444 | Item 4: 25.000000 445 | From C: The sum of the elements is: 446 | Sum: 75.000000 447 | \end{lstlisting} 448 | \clearpage 449 | 450 | 451 | 452 | 453 | 454 | \subsubsection{Pascal source files} 455 | \lstset{style=myPascal} 456 | 457 | \subsubsection*{Unit 'unit3.pas'} 458 | We link to the C object file via the following Pascal unit. 459 | \lstinputlisting{../arrfun/unit3.pas} 460 | 461 | \subsubsection*{Program 'prog3.pas'} 462 | \lstinputlisting{../arrfun/prog3.pas} 463 | 464 | \subsubsection*{Compiling the Pascal code} 465 | Compile the Pascal program (output the file as \mytext{prog3.exe}): 466 | 467 | \mytext{fpc -Px86\_64 prog3.pas -oprog3.exe} 468 | 469 | This should produce a file \mytext{prog3.exe}. If you run the program (by typing its name in the terminal), you will get 470 | 471 | \lstset{style=myBash} 472 | \begin{lstlisting} 473 | From Pascal: The multiplied elements are: 474 | Item 0: 5.00 475 | Item 1: 1.60 476 | Item 2: 2.83 477 | Item 3: 1.01 478 | Item 4: 0.28 479 | 480 | From Pascal: The sum of the elements is: 481 | Sum : 22.2 482 | \end{lstlisting} 483 | \clearpage 484 | 485 | \section{Linking to Static and Shared Object C libraries} 486 | The code in this section calculates \textit{Fibonacci} numbers using recursion, 487 | it also mixes 488 | in some array functions used in the previous section. 489 | 490 | \subsection{C source files for calculating Fibonacci numbers} 491 | \lstset{style=myC} 492 | 493 | \subsubsection*{Header file 'fibonacci.h'} 494 | \lstinputlisting{../fibonacci/fibonacci.h} 495 | 496 | \subsubsection*{Module 'fibonacci.c'} 497 | \lstinputlisting{../fibonacci/fibonacci.c} 498 | 499 | \newpage 500 | Start by creating object-code files, as before: 501 | 502 | \mytext{gcc -c fibonacci.c} 503 | 504 | You should end up with a `fibonacci.o' object file. 505 | 506 | \subsection{Creating a Static C library (aka an archive)} 507 | In a terminal, type: 508 | 509 | \mytext{ar cr libfibonacci.a fibonacci.o} 510 | 511 | You should end up with a static library named \mytext{libfibonacci.a}. 512 | A static library is little more than an archive of object-code file(s). 513 | 514 | \subsubsection{Using the Static Library from Pascal} 515 | \lstset{style=myPascal} 516 | 517 | You can now call the functions in the 'libfibonacci.a' library as follows: 518 | 519 | \subsubsection*{Unit 'ulibfibStat.pas'} 520 | We link to the C object file via the following Pascal unit. 521 | \lstinputlisting{../fibonacci/ulibfibStat.pas} 522 | 523 | \newpage 524 | \subsubsection*{Program 'fibStat.pas'} 525 | \lstinputlisting{../fibonacci/fibStat.pas} 526 | 527 | \newpage 528 | \subsubsection*{Compiling the Pascal code} 529 | Compile the Pascal program (output the file as \mytext{fibStat.exe}): 530 | 531 | \mytext{fpc -Px86\_64 fibStat.pas -ofibStat.exe} 532 | 533 | This should produce a file \mytext{fibStat.exe}. If you run the program, 534 | you will get 535 | 536 | \lstset{style=myBash} 537 | \begin{lstlisting} 538 | From Pascal, referencing the C Static Library: 539 | Fib(0) = 0 540 | Fib(1) = 1 541 | Fib(2) = 1 542 | Fib(3) = 2 543 | Fib(4) = 3 544 | Fib(5) = 5 545 | Fib(6) = 8 546 | Fib(7) = 13 547 | Fib(8) = 21 548 | Fib(9) = 34 549 | Fib(10) = 55 550 | Fib(11) = 89 551 | Fib(12) = 144 552 | Fib(13) = 233 553 | Fib(14) = 377 554 | Fib(15) = 610 555 | Fib(16) = 987 556 | Fib(17) = 1597 557 | 558 | Calculate Fibonacci numbers for the following vector of values: 559 | [ 3 5 7 17 ] 560 | Fib(vec[0]) = 2 561 | Fib(vec[1]) = 5 562 | Fib(vec[2]) = 13 563 | Fib(vec[3]) = 1597 564 | \end{lstlisting} 565 | 566 | You can test that it's static by simply renaming (or deleting) the `libfibonacci.a' 567 | file and running the program again. If it runs as before, it's proof. 568 | \clearpage 569 | 570 | \subsection{Creating a Shared C library (aka a Shared Object file)} 571 | In a terminal, type: 572 | 573 | \mytext{gcc -shared fibonacci.o -o libfibonacci.so} 574 | 575 | You should end up with a Shared Object (dynamic lib) named \mytext{libfibonacci.so} 576 | that you can link to, 577 | just as before. For large programs you may notice that the final executable is smaller, 578 | because you've linked 579 | dynamically to the library, not statically, which means the library's code isn't 580 | included in the executable. For small programs you won't notice this. 581 | 582 | \subsubsection{Using the Shared Library from Pascal}\lstset{style=myPascal} 583 | You can now call the functions in the 'libfibonacci.so' library as follows: 584 | 585 | \subsubsection*{Unit 'ulibfibDyn.pas'} 586 | We link to the C object file via the following Pascal unit. 587 | \lstinputlisting{../fibonacci/ulibfibDyn.pas} 588 | 589 | 590 | \newpage 591 | \subsubsection*{Program 'fibDyn.pas'} 592 | \lstinputlisting{../fibonacci/fibDyn.pas} 593 | 594 | \clearpage 595 | \subsubsection*{Compiling the Pascal code} 596 | Compile the Pascal program (output the file as \mytext{fibDyn.exe}): 597 | 598 | \mytext{fpc -Px86\_64 fibDyn.pas -ofibDyn.exe} 599 | 600 | This should produce a file \mytext{fibDyn.exe}. If you run the program, 601 | you should get 602 | 603 | \lstset{style=myBash} 604 | \begin{lstlisting} 605 | From Pascal, referencing the Shared Object (Dynamic Library): 606 | Fib(8) = 21 607 | Fib(9) = 34 608 | Fib(10) = 55 609 | Fib(11) = 89 610 | Fib(12) = 144 611 | Fib(13) = 233 612 | Fib(14) = 377 613 | Fib(15) = 610 614 | Fib(16) = 987 615 | Fib(17) = 1597 616 | Fib(18) = 2584 617 | Fib(19) = 4181 618 | Fib(20) = 6765 619 | Fib(21) = 10946 620 | Fib(22) = 17711 621 | Fib(23) = 28657 622 | 623 | Calculate Fibonacci numbers for the following vector of values: 624 | [ 18 15 17 23 ] 625 | Fib(vec[0]) = 2584 626 | Fib(vec[1]) = 610 627 | Fib(vec[2]) = 1597 628 | Fib(vec[3]) = 28657 629 | \end{lstlisting} 630 | 631 | You can test that it has linked dynamicly 632 | by simply renaming (or deleting) the `libfibonacci.so' 633 | file and running the program again. If it doesn't run as before, it's proof, on Windows 634 | you should get a dialogue as shown below: 635 | 636 | \begin{figure}[hbtp] 637 | \centering 638 | \includegraphics[scale=1]{../fibonacci/fibDynSystemError.png} 639 | \caption{Windows error dialogue for missing library} 640 | \end{figure} 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | %CSparse 675 | %Compiling 676 | %All MingGW gcc commands (don't type the $ sign...) 677 | % 678 | % Copy the header file cs.h to Source and do "gcc -c *.o" 679 | % Then in the same directory do "ar cr libcsparse.a *.o" 680 | % 681 | %Demo 1 682 | %$ gcc ​-o cs_demo1 cs_demo1.c ./libcsparse.a -lm 683 | % 684 | %Demo 2 685 | %First compile cs_demo to object-code (to get cs_demo.o) since it contains functions used by cs_demo2 and cs_demo3: 686 | % 687 | %$ gcc -c cs_demo.c -I../Include 688 | % 689 | %Now type: 690 | % 691 | %$ gcc -o cs_demo2 cs_demo.o cs_demo2.c -I../Include ../Source/libcsparse.a 692 | % 693 | %Demo 3 694 | % As for cs_demo2 695 | % 696 | 697 | \begin{thebibliography}{1} 698 | 699 | \bibitem{cinfree} Marcou, Engler and Varnek. {\em How to use C code in Free Pascal projects}. University of Strasbourg, 23 July 2009. 700 | 701 | \end{thebibliography} 702 | 703 | \end{document} 704 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | Refer to **Creating Pascal bindings for C (v1.0).pdf** 2 | 3 | 4 | **CinFreePascal.pdf** is here for reference only. 5 | -------------------------------------------------------------------------------- /fibonacci/fibDyn.pas: -------------------------------------------------------------------------------- 1 | program fibDyn; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | ulibfibDyn; 7 | 8 | var 9 | i: integer; 10 | vec: array[0..3] of integer = (18, 15, 17, 23); 11 | copyvec: array[0..3] of integer = (18, 15, 17, 23); 12 | len: integer = length(vec); 13 | 14 | begin 15 | WriteLn('From Pascal, referencing the Shared Object (Dynamic Library):'); 16 | 17 | for i := 8 to 23 do 18 | WriteLn('Fib(', i, ') = ', fib(i)); 19 | 20 | fibseries(vec, len); 21 | WriteLn(); 22 | WriteLn('Calculate Fibonacci numbers for the following vector of values:'); 23 | Write('[ '); 24 | for i := 0 to (len - 1) do 25 | Write(copyvec[i], ' '); 26 | WriteLn(']'); 27 | 28 | for i := 0 to (len - 1) do 29 | WriteLn('Fib(vec[', i, ']) = ', vec[i]); 30 | end. 31 | -------------------------------------------------------------------------------- /fibonacci/fibDynSystemError.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamhunter/pascal-bindings-for-c/32546595442182afc187f2afea04fc813dde5853/fibonacci/fibDynSystemError.png -------------------------------------------------------------------------------- /fibonacci/fibStat.pas: -------------------------------------------------------------------------------- 1 | program fibStat; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | ulibfibStat; 7 | 8 | var 9 | i: integer; 10 | vec: array[0..3] of integer = (3, 5, 7, 17); 11 | copyvec: array[0..3] of integer = (3, 5, 7, 17); 12 | len: integer = length(vec); 13 | 14 | begin 15 | WriteLn('From Pascal, referencing the C Static Library:'); 16 | 17 | for i := 0 to 17 do 18 | WriteLn('Fib(', i, ') = ', fib(i)); 19 | 20 | fibseries(vec, len); 21 | WriteLn(); 22 | WriteLn('Calculate Fibonacci numbers for the following vector of values:'); 23 | Write('[ '); 24 | for i := 0 to (len - 1) do 25 | Write(copyvec[i], ' '); 26 | WriteLn(']'); 27 | 28 | for i := 0 to (len - 1) do 29 | WriteLn('Fib(vec[', i, ']) = ', vec[i]); 30 | end. 31 | -------------------------------------------------------------------------------- /fibonacci/fibonacci.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: fibonacci.c 3 | * 4 | */ 5 | 6 | int fib(int val) 7 | // Recursive function to compute Fibonacci number, counting from 0 8 | { 9 | if (val < 0) // 'Wrong' input will return -1 10 | return - 1; 11 | else if (val == 0) 12 | return 0; 13 | else if ((val == 1)||(val == 2)) 14 | return 1; 15 | else 16 | return fib(val - 2) + fib(val - 1); 17 | } 18 | 19 | void fibseries(int series[], int len) 20 | // Compute nth Fibonacci number for series of values 21 | { 22 | int i; 23 | for (i = 0; i < len; i++) 24 | { 25 | series[i] = fib(series[i]); 26 | } 27 | } -------------------------------------------------------------------------------- /fibonacci/fibonacci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: fibonacci.h 3 | * 4 | */ 5 | 6 | #ifndef FIBONACCI_H 7 | #define FIBONACCI_H 8 | 9 | /* Function prototypes */ 10 | int fib(int a); 11 | void fibseries(int series[], int len); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /fibonacci/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: main.c 3 | * 4 | */ 5 | 6 | #include 7 | #include "fibonacci.h" 8 | 9 | int main(void) 10 | { 11 | int i, j; 12 | int val = 13; 13 | printf("The %dth Fibonacci number is = %d\n", val, fib(val)); 14 | 15 | 16 | int vals[4] = {7, 9, 11, val}; 17 | int copyvals[4] = {7, 9, 11, val}; 18 | const int len = 4; 19 | 20 | int mats[2][2] = {{3, 5}, {7, 9}}; 21 | 22 | fibseries(vals, len); 23 | // print each element's fib(val) 24 | for (i = 0; i < len; i++) 25 | { 26 | printf("Element[%d]: The %dth Fibonacci number is = %d\n", i, copyvals[i], vals[i] ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /fibonacci/ulibfibDyn.pas: -------------------------------------------------------------------------------- 1 | unit ulibfibDyn; 2 | 3 | interface 4 | // leave this empty 5 | 6 | // The function prototypes in fibonacci.h are: 7 | // int fib(int a); 8 | // void fibseries(int series[], int len); 9 | 10 | // The equivalent Pascal functions are (and link to external shared object): 11 | function fib(a:longint):longint; cdecl; external 'libfibonacci.so'; 12 | procedure fibseries(series:plongint; len:longint); cdecl; external 'libfibonacci.so'; 13 | 14 | implementation 15 | // leave this empty 16 | 17 | end. 18 | -------------------------------------------------------------------------------- /fibonacci/ulibfibStat.pas: -------------------------------------------------------------------------------- 1 | unit ulibfibStat; 2 | 3 | {$linklib 'libfibonacci.a'} // link to our static library libfibonacci.a 4 | 5 | interface 6 | // leave this empty 7 | 8 | // The function prototypes in fibonacci.h (the C header file) are: 9 | // int fib(int a); 10 | // void fibseries(int series[], int len); 11 | 12 | // The equivalent Pascal functions are: 13 | function fib(a:longint):longint; cdecl; external; 14 | procedure fibseries(series:plongint; len:longint); cdecl; external; 15 | 16 | implementation 17 | // leave this empty 18 | 19 | end. 20 | -------------------------------------------------------------------------------- /hello/hello.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: hello.c 3 | * 4 | */ 5 | 6 | #include 7 | #include "hello.h" 8 | 9 | void printhello(void) 10 | { 11 | printf("Hello, World!"); 12 | printf("\n"); 13 | } 14 | 15 | void printhelloperson(char *name) 16 | { 17 | printf("Hello "); 18 | printf("%s\n", name); 19 | } 20 | -------------------------------------------------------------------------------- /hello/hello.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: hello.h 3 | * 4 | */ 5 | 6 | #ifndef HELLO_H 7 | #define HELLO_H 8 | 9 | void printhello(void); 10 | void printhelloperson(char *); 11 | 12 | #endif -------------------------------------------------------------------------------- /hello/main2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: main2.c 3 | * 4 | */ 5 | 6 | #include 7 | #include "hello.h" 8 | 9 | int main(void) 10 | { 11 | char *name = "John Smith"; // same as: char name[] = "John Smith"; 12 | printf("From C:\n"); 13 | printhello(); 14 | printhelloperson(name); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /hello/prog2.pas: -------------------------------------------------------------------------------- 1 | program prog2; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | unit2; 7 | 8 | var 9 | name: pchar; // ^char will also work 10 | 11 | begin 12 | name := 'Joe Public'; 13 | writeln('From Pascal, calling C functions:'); 14 | PrintHello; 15 | PrintHelloPerson(name); 16 | end. 17 | -------------------------------------------------------------------------------- /hello/unit2.pas: -------------------------------------------------------------------------------- 1 | unit unit2; 2 | 3 | {$link hello.o} // link to C object-code 4 | 5 | {$ifdef WINDOWS} 6 | {$linklib libmsvcrt} 7 | {$else} // Linux 8 | {$linklib libc} // or try {$linklib c} 9 | {$endif} 10 | 11 | {Note the difference in use of $link and $linklib above, 12 | the first is for object files, the latter for libraries.} 13 | 14 | interface 15 | // leave this empty 16 | 17 | uses ctypes; 18 | 19 | procedure printhello; cdecl; external; 20 | procedure printhelloperson(name : pchar); cdecl; external; 21 | // function prototypes to match that of hello.h exactly, even the case! 22 | 23 | implementation 24 | // leave this empty 25 | 26 | end. 27 | -------------------------------------------------------------------------------- /sum/main1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: main1.c 3 | * 4 | */ 5 | 6 | #include 7 | #include "sum.h" 8 | 9 | int main(void) 10 | { 11 | int a = 17; 12 | int b = 19; 13 | printf("From C: The sum of %d and %d is %d\n", a, b, sum(a,b)); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /sum/prog1.pas: -------------------------------------------------------------------------------- 1 | program prog1; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | unit1; 7 | 8 | var 9 | a, b: integer; 10 | 11 | begin 12 | a := 12; // 17 in C program 13 | b := 51; // 19 in C program 14 | writeln('From Pascal: The sum of ', a, ' and ', b, ' is ', sum(a, b)); 15 | end. 16 | -------------------------------------------------------------------------------- /sum/sum.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: sum.c 3 | * 4 | */ 5 | 6 | #include "sum.h" 7 | 8 | int sum(int x, int y) 9 | { 10 | return x + y; 11 | } 12 | -------------------------------------------------------------------------------- /sum/sum.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Filename: sum.h 3 | * 4 | */ 5 | 6 | #ifndef SUM_H 7 | #define SUM_H 8 | 9 | // Function prototype(s) 10 | int sum(int x, int y); 11 | 12 | #endif -------------------------------------------------------------------------------- /sum/unit1.pas: -------------------------------------------------------------------------------- 1 | unit unit1; 2 | 3 | {$link sum.o} // link to C object-code, same as {$L sum.o} 4 | 5 | interface 6 | // leave this empty 7 | 8 | uses ctypes; // need to specify this else FPC won't compile 9 | 10 | function sum(x, y : cint32) : cint32; cdecl; external; 11 | // function args and types to match the ones as defined in sum.h 12 | 13 | implementation 14 | // leave this empty 15 | 16 | end. 17 | --------------------------------------------------------------------------------