{"id":665,"date":"2024-03-17T21:57:36","date_gmt":"2024-03-17T20:57:36","guid":{"rendered":"https:\/\/jorgeturiel.es\/?p=665"},"modified":"2024-03-17T21:57:36","modified_gmt":"2024-03-17T20:57:36","slug":"accediendo-a-bibliotecas-escritas-en-c","status":"publish","type":"post","link":"https:\/\/jorgeturiel.es\/?p=665","title":{"rendered":"Accediendo a bibliotecas escritas en C"},"content":{"rendered":"\n<p>Las librer\u00edas de programaci\u00f3n son herramientas para hacer que el desarrollo de software sea m\u00e1s eficiente. Proporcionan fragmentos de c\u00f3digo reutilizables que los desarrolladores pueden utilizar para programar de forma r\u00e1pida y sencilla.<\/p>\n\n\n\n<p>En Windows son los famosos archivos que tiene por extensi\u00f3n .DLL, en Linux suelen terminar su nombre en .so<\/p>\n\n\n\n<p>Una biblioteca escrita en C, tiene un archivo de cabecera (archivo con extensi\u00f3n .h) el cual contiene la definici\u00f3n de las funciones, tipos de datos, etc. que se definen en esta librer\u00eda.<\/p>\n\n\n\n<p>Desde Free Pascal, es sencillo o relativamente sencillo hacer uso de estas bibliotecas, si se escribe un archivo de cabecera pero usando el lenguaje y la sintaxis de Free Pascal. <\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Introducci\u00f3n<\/h2>\n\n\n\n<p>Personalmente he escrito varias cabeceras para diversas bibliotecas. Para ello me he apoyado en la Wiki de pascal, en las siguientes entradas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/wiki.freepascal.org\/Pascal_for_C_users\">Pascal for C users<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/wiki.freepascal.org\/Creating_bindings_for_C_libraries\">Creating bindings for C libraries<\/a> <\/li>\n<\/ul>\n\n\n\n<p>Adem\u00e1s del foro de <a href=\"https:\/\/forum.lazarus.freepascal.org\/index.php\">Lazarus y Free Pascal<\/a>. <\/p>\n\n\n\n<p>Adem\u00e1s, con lo aprendido he ido haciendo notas, que me han ayudado. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Definiendo la biblioteca.<a href=\"https:\/\/github.com\/Blueicaro\/Pascal-Librealsense\/blob\/main\/info\/NotasConversion.md#notas-sobre-la-conversi\u00f3n\"><\/a><\/h2>\n\n\n\n<p>El nombre de la librer\u00eda externa  se debe definir como una constante, y usar los condicionantes de compilaci\u00f3n, por ejemplo:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >const\n{$IFDEF MSWINDOWS}\n  REALSENSE_DLL='realsense2.dll';\n{$ENDIF}\n{$IFDEF LINUX}\n  REALSENSE_DLL='realsense2.so';\n{$ENDIF}  <\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Funciones void<\/h2>\n\n\n\n<p><a href=\"https:\/\/github.com\/Blueicaro\/Pascal-Librealsense\/blob\/main\/info\/NotasConversion.md#funciones-void\"><\/a>Las funciones void (que no retornan nada).<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:c decode:true \" >void rs2_delete_context(rs2_context* context);<\/pre><\/div>\n\n\n\n<p>Se declaran en Free Pascal como procedimientos (<em>procedure<\/em>)<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \" >procedure rs2_delete_context(context: prs2_context); cdecl; external REALSENSE_DLL;<\/pre><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code> \nLas bibliotecas  son declaradas como externa (<em>external<\/em>) y el tipo de llamada cdecl por convenci\u00f3n.  \n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Funciones que retornan un puntero<a href=\"https:\/\/github.com\/Blueicaro\/Pascal-Librealsense\/blob\/main\/info\/NotasConversion.md#funciones-que-retornan-un-puntero\"><\/a><\/h2>\n\n\n\n<p>Una funci\u00f3n que retorna un punto como la siguiente:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:c decode:true \" >rs2_context* rs2_create_context(int api_version, rs2_error** error);<\/pre><\/div>\n\n\n\n<p>Es declarada como una funci\u00f3n que devuelve un puntero.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  rs2_context = record\nend;\nprs2_context = ^rs2_context;    \n  (...)\nfunction rs2_create_context(api_version: integer; aerror: Pointer): prs2_context;cdecl; external REALSENSE_DLL;<\/pre><\/div>\n\n\n\n<p>El puntero debe apuntar a un tipo de dato o estructura conocida. Pero hay veces que no es posible como la definici\u00f3n anterior.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cuando la funci\u00f3n retorna un estructura desconocida u opaca<a href=\"https:\/\/github.com\/Blueicaro\/Pascal-Librealsense\/blob\/main\/info\/NotasConversion.md#cuando-la-funci\u00f3n-retorna-un-estructura-desconocida-u-opaca\"><\/a><\/h2>\n\n\n\n<p>Algunas declaraciones en C devuelve una estructura que no es conocida, o puede ser diferente dependiendo de la situaci\u00f3n. Por ejemplo:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:c decode:true \" >typedef struct rs2_context rs2_context;<\/pre><\/div>\n\n\n\n<p>Esto, en Free Pascal, se denomina una estructura opaca, de acuerdo con el post: <a href=\"https:\/\/forum.lazarus.freepascal.org\/index.php\/topic,61311.0.html\">https:\/\/forum.lazarus.freepascal.org\/index.php\/topic,61311.0.html<\/a><\/p>\n\n\n\n<p>Se declaran as\u00ed:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  rs2_context = record\nend;\nprs2_context = ^rs2_context;<\/pre><\/div>\n\n\n\n<pre id=\"block-5349a509-c971-41a2-8f2c-f74de61fa1f5\" class=\"wp-block-code\"><code>Otra opci\u00f3n es usar un punto opaco.<\/code><\/pre>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >Type\n prs2_context=POpaqueData;<\/pre><\/div>\n\n\n\n<p>M\u00e1s informaci\u00f3n en la ayuda de Free Pascal:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.freepascal.org\/docs-html\/rtl\/system\/popaquedata.html\">https:\/\/www.freepascal.org\/docs-html\/rtl\/system\/popaquedata.html<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.freepascal.org\/docs-html\/rtl\/system\/topaquedata.html\">https:\/\/www.freepascal.org\/docs-html\/rtl\/system\/topaquedata.html<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Cuando una funci\u00f3n es un callback<a href=\"https:\/\/github.com\/Blueicaro\/Pascal-Librealsense\/blob\/main\/info\/NotasConversion.md#cuando-una-funci\u00f3n-es-un-callback\"><\/a><\/h2>\n\n\n\n<p>La siguiente declaraci\u00f3n es un callback en C.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:c decode:true \" >typedef struct rs2_devices_changed_callback rs2_devices_changed_callback;\n\ntypedef void (*rs2_devices_changed_callback_ptr)(rs2_device_list*, rs2_device_list*, void*);<\/pre><\/div>\n\n\n\n<p>En Pascal se debe definir de la siguiente manera:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type \n  pRS2_devices_changed_callback = ^RS2_devices_changed_callback;\n\n  RS2_devices_changed_callback = procedure (DeviceList1: pRS2_Device_List; \n                                 DeviceList2: pRS2_Device_List);cdecl;external REALSENSE_DLL;<\/pre><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Estructura con una rutina en la declaraci\u00f3n<\/h2>\n\n\n\n<p>La siguiente estructura en C<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:c decode:true \" >typedef struct rs2_software_video_frame\n{\nvoid* pixels;\nvoid(*deleter)(void*);\nint stride;\nint bpp;\nrs2_time_t timestamp;\nrs2_timestamp_domain domain;\nint frame_number;\nconst rs2_stream_profile* profile;\nfloat depth_units;\n} rs2_software_video_frame;<\/pre><\/div>\n\n\n\n<p>En Free Pascal ser\u00eda:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  Trs2_software_video_frame = record\n  pixels: pvoid;\n  deleter: TDeleterProc;\n  stride: integer;\n  timestamp: Trs2_time_t;\n  domain: Trs2_timestamp_domain;\n  frame_number: integer;\n  profile: pRS2_stream_profile;\n  depth_units: single;\nend; <\/pre><\/div>\n\n\n\n<p>La l\u00ednea siguiente, ser\u00eda un puntero a procedimiento<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:c decode:true \" >void(*deleter)(void*);<\/pre><\/div>\n\n\n\n<p>Su conversi\u00f3n ser\u00eda:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n\nTDeleterProc = procedure(arg: Pointer); cdecl;external REALSENSE_DLL;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Conversi\u00f3n de tipos de datos<a href=\"https:\/\/github.com\/Blueicaro\/Pascal-Librealsense\/blob\/main\/info\/NotasConversion.md#conversi\u00f3n-de-tipos-de-datos\"><\/a><\/h2>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th>C<\/th><th>Pascal<\/th><th>Bits<\/th><\/tr><\/thead><tbody><tr><td>char<\/td><td>char<\/td><td>8 bits(ascci)<\/td><\/tr><tr><td>signed char<\/td><td>shortint<\/td><td>8 bits con signo<\/td><\/tr><tr><td>unsigned char<\/td><td>byte<\/td><td>8 bits sin signo<\/td><\/tr><tr><td>char<\/td><td>pchar<\/td><td>32 bit (puntero a null-terminated string)<\/td><\/tr><tr><td>short int<\/td><td>smalint<\/td><td>16 bits con signo<\/td><\/tr><tr><td>unsigned short int<\/td><td>word<\/td><td>16 sin signo<\/td><\/tr><tr><td>int<\/td><td>integer<\/td><td>16 (o 32) bits (gen\u00e9rico) con signo<\/td><\/tr><tr><td>unsigned int<\/td><td>cardinal<\/td><td>16 (o 32) bits (gen\u00e9rico) sin signo<\/td><\/tr><tr><td>float<\/td><td>single<\/td><td>32 bits con signo<\/td><\/tr><tr><td>long long int<\/td><td>Int64<\/td><td>64 bits con signo<\/td><\/tr><tr><td>double<\/td><td>double<\/td><td>64 bits con signo<\/td><\/tr><tr><td>unsigned long long int<\/td><td>uInt64<\/td><td>64 sin signo<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><br><\/p>\n\n\n\n<p><br><br><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Las librer\u00edas de programaci\u00f3n son herramientas para hacer que el desarrollo de software sea m\u00e1s eficiente. Proporcionan fragmentos de c\u00f3digo reutilizables que los desarrolladores pueden utilizar para programar de forma r\u00e1pida y sencilla. En Windows son los famosos archivos que tiene por extensi\u00f3n .DLL, en Linux suelen terminar su nombre en .so Una biblioteca escrita [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":669,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,25,26,1],"tags":[32,23,21,24],"class_list":["post-665","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-lazarus","category-pascal","category-programacion","category-sin-categoria","tag-free-pascal","tag-lazarus","tag-pascal","tag-programacion"],"_links":{"self":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/665","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=665"}],"version-history":[{"count":4,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/665\/revisions"}],"predecessor-version":[{"id":670,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/665\/revisions\/670"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/media\/669"}],"wp:attachment":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=665"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=665"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=665"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}