DECLARE LIBRARY: Difference between revisions

From QB64 Phoenix Edition Wiki
Jump to navigation Jump to search
(Created page with "The '''DECLARE LIBRARY''' declaration allows the use of external library SUB and FUNCTION procedures supported by QB64. {{PageSyntax}} : '''DECLARE''' [DYNAMIC|CUSTOMTYPE|STATIC] '''LIBRARY''' [{''"Library_filename"''|''"Headerfile"''}] : {SUB|FUNCTION} [''procedure_name'' {{KW|ALIAS}}] ''library_procedure'' ([{{KW|BYVAL}}] ''parameter {{KW|AS}}'', ...) ::. ::. 'other SUBs or Functions as required ::. : '''END DECLARE''' {{Parameters}} * The {{Paramet...")
 
No edit summary
 
(15 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The '''DECLARE LIBRARY''' declaration allows the use of external library [[SUB]] and [[FUNCTION]] procedures supported by QB64.
The '''DECLARE LIBRARY''' declaration allows for the utilization of external library [[SUB]] and [[FUNCTION]] procedures.




{{PageSyntax}}
{{PageSyntax}}
: '''DECLARE''' [DYNAMIC|CUSTOMTYPE|STATIC] '''LIBRARY''' [{''"Library_filename"''|''"Headerfile"''}]
: '''DECLARE [DYNAMIC|CUSTOMTYPE|STATIC] LIBRARY''' [''"Library_name"''][, ''"Library_name2"''][, ...]
: {[[SUB]]|[[FUNCTION]]} [''procedure_name'' {{KW|ALIAS}}] ''library_procedure'' ([{{KW|BYVAL}}] ''parameter {{KW|AS}}'', ...)
::{[[SUB]]|[[FUNCTION]]} ''Procedure_name'' ['''ALIAS''' ''Library_procedure''] ([[BYVAL]] ''Parameter''[{suffix| [[AS]] [[Variable Types|type]][, ''Parameter2''...][, ...]])
::.
::.
::. 'other SUBs or Functions as required
::. ' Other SUBs or FUNCTIONs as required
::.
::.
: '''END DECLARE'''
: '''END DECLARE'''




{{Parameters}}
{{PageDescription}}
* The {{Parameter|Library_filename}} is needed if a Library is not already loaded by QB64. Do not include the ''.DLL'', ''LIB'' or ''.H'' file extension.
* The declaration can be used with:
** It's always a good idea to try declaring Windows API libraries without a {{Parameter|Library_filename}} first, as most Windows headers are already included in QB64 source.
** C/C++ sub-procedures files (''.h'' and ''.hpp'')
* Begin the {{Parameter|Library_filename}} with '''./''' or '''.\''' to make it relative to the path where your source file is saved, so you can keep all your project files together.
** Dynamically linked libraries and shared object files (''.dll'', ''.so'' and ''.dylib'')
* {{Parameter|Procedure_name}} is any program procedure name you want to designate by using [[ALIAS]] with the {{Parameter|Library_procedure}} name.  
** Static libraries (''.a'')
* {{Parameter|Library procedure}} is the actual procedure name used inside of the library or header file.
** Object files (''.o'')
* ''Library file names'' can be listed to combine more than one supported file name or path into one DECLARE LIBRARY block ('''except for dynamically linked libraries and shared object files'''). Do not include any file extension (''.h'', ''.dll'', ''.a'' etc.).
* The dynamically linked library or shared object file can be in a relative/absolute path specified along with the library name, in the operating system's directory (e.g., C:\Windows\System32), or in the QB64 directory (alongside your program's executable).
* Specify ''""'' as the library file name to inform QB64 that the function exists in a library that is already linked and that it must define the C function before calling it, as well as allowing QB64 code to call it.
* It's a good idea to try declaring Operating System API libraries without a library file name first, as most common Operating System headers are already included in QB64 source.
* When using a procedure from a dynamically linked library or shared object (''.dll'', ''.so'' and ''.dylib'' files) use '''DECLARE DYNAMIC LIBRARY'''.
* When using a procedure from a static library (''.a'' files) use '''DECLARE STATIC LIBRARY'''.
* ''Procedure_name'' can be any desired procedure name designated by using [[ALIAS]] with the ''Library_procedure'' name following. Enclose ''Library_procedure'' in ''""'' when using a C++ function with the scope operator (e.g., "std::clamp").
* ''Parameters'' used by the library procedure can be passed by value ([[BYVAL]]) when needed, except for [[STRING]] values.
* QB64 [[STRING]]s are passed to external libraries as pointers to first character. Many external library procedures expect strings to be NULL terminated. Terminate [[STRING]]s using [[CHR$]](0) wherever it is needed.
* Declarations can be made inside of [[SUB]] or [[FUNCTION]] procedures. Declarations do not need to be at program start.
* C/C++ procedures can use a header file name and the file code must be included with program code.
* C/C++ header files cannot be used with '''DECLARE DYNAMIC LIBRARY'''. Existence of any ''.h'' or ''.hpp'' file of the same name as the dynamically linked library or shared object file will cause DECLARE DYNAMIC LIBRARY to fail.
* The [[_OFFSET]] in memory can be used in '''CUSTOMTYPE''', '''STATIC''' and '''DYNAMIC LIBRARY''' declarations.
* '''DECLARE DYNAMIC LIBRARY''' let's you specify any [[SUB]]/[[FUNCTION]] calling format you wish, but if the size of the parameters does not match, the size expected within the library, your code will probably cause a GPF (General Protection Fault). It is important to understand that pointers (if required) will be 32-bits in size (the equivalent of a [[LONG]]) when creating a 32-bit program (even under 64-bit Windows).
* '''STATIC''' is the same as '''DYNAMIC''' except that it prioritizes linking to static libraries (''.a'' and ''.o'' files) over dynamically linked libraries and shared object files, if both exist.
* '''CUSTOMTYPE''' is already implied when using '''DECLARE DYNAMIC LIBRARY'''. This type of library just allows the same flexibility to apply when referencing STATIC libraries that are used to refer to dynamic libraries.
* [[SUB]] procedures using '''DECLARE CUSTOMTYPE LIBRARY''' API procedures '''may error'''. Try '''DYNAMIC''' with the dynamically linked library or shared object file name.
* It is up to the user to document and determine the suitability of all libraries and procedures they choose to use. QB64 cannot guarantee that any procedure will work and cannot guarantee any troubleshooting help.
* QB64 version 1.000 and up produce standalone executables. External dynamically linked libraries or shared object files must be distributed with your program.
* What libraries are or aren't automatically used in the linking process is not formally defined, nor is it guaranteed to stay that way in future versions of QB64.




===Library Types===
{{PageParameters}}
* '''[[DECLARE DYNAMIC LIBRARY|DYNAMIC]]''' links a program to functions in dynamically linkable libraries. At present, only .DLL files are supported
* The {{Parameter|Library_name}} is needed if a library is not already loaded by QB64. Do not include the file extension. Begin the {{Parameter|Library_name}} with '''./''' or '''.\''' to make it relative to the path where your source file is saved, so you can keep all your project files together.
* '''CUSTOMTYPE''' is already implied when using [[DECLARE DYNAMIC LIBRARY]]. This type of library just allows the same flexibility to apply when referencing STATIC libraries that are used to refer to dynamic libraries. Supports shared object (*.so) libraries.
* {{Parameter|Procedure_name}} is any program procedure name you want to designate by using [[ALIAS]] with the {{Parameter|Library_procedure}} name.
* '''STATIC''' is the same as [[DECLARE LIBRARY]] except that it prioritizes linking to static libraries (*.a/*.o) over shared object (*.so) libraries, if both exist. As Windows doesn't use shared libraries (DLLs are different) this does not affect Windows users.
* {{Parameter|Library procedure}} is the actual procedure name used inside of the library or header file.
 


{{PageDescription}}
* The declaration can be used with C++ sub-procedures, Windows API and QB64 SDL (versions prior to 1.000)/OpenGL (version 1.000 and up) Libraries.
* ''Library filename''s can be listed to combine more than one DLL or Header file name or path into one DECLARE LIBRARY block.
* C procedures can use a header file name. File code must be included with program code. Do not include the ''.h'' extension.
* ''Parameters'' used by the Library procedure must be passed by value ([[BYVAL]]) except for [[STRING]] characters.
* When using a procedure from an '''unsupported''' Dynamic Link Library (DLL file) use [[DECLARE DYNAMIC LIBRARY]].


* The [[_OFFSET]] in memory can be used in '''CUSTOMTYPE''', '''STATIC''' and '''DYNAMIC LIBRARY''' declarations.
{{PageAvailability}}
* Declarations can be made inside of [[SUB]] or [[FUNCTION]] procedures. Declarations do not need to be at program start.
<!-- QB64 = a version or none, QBPE = a version or all, Platforms = yes or no -->
* '''NOTE: It is up to the user to document and determine the suitability of all Libraries and procedures they choose to use! QB64 cannot guarantee that any procedure will work and cannot quarantee any troubleshooting help.'''
<gallery widths="48px" heights="48px" mode="nolines">
File:Qb64.png|'''v0.923'''
File:Qbpe.png|'''all'''
File:Apix.png
File:Win.png|'''yes'''
File:Lnx.png|'''yes'''
File:Osx.png|'''yes'''
</gallery>
<!-- additional availability notes go below here -->
* Available for ''Linux'' and ''macOS'' since '''QB64 v0.940'''




{{PageExamples}}
{{PageExamples}}
''Example 1:'' Using an '''SDL''' library procedure as a program SUB procedure to move the mouse pointer to a coordinate (works in versions prior to 1.000):
;Example 1: Using GLUT library procedure as a program SUB procedure to set the mouse pointer style.
{{CodeStart}} '' ''
{{CodeStart}}
{{Cl|CONST}} CURSOR_NORMAL = {{Text|1|#F580B1}}
{{Cl|CONST}} CURSOR_HAND = {{Text|2|#F580B1}}
{{Cl|CONST}} CURSOR_HELP = {{Text|4|#F580B1}}
{{Cl|CONST}} CURSOR_CYCLE = {{Text|7|#F580B1}}
{{Cl|CONST}} CURSOR_TEXT = {{Text|8|#F580B1}}
{{Cl|CONST}} CURSOR_CROSSHAIR = {{Text|3|#F580B1}}
{{Cl|CONST}} CURSOR_UP_DOWN = {{Text|10|#F580B1}}
{{Cl|CONST}} CURSOR_LEFT_RIGHT = {{Text|11|#F580B1}}
{{Cl|CONST}} CURSOR_LEFT_RIGHT_CORNER = {{Text|16|#F580B1}}
{{Cl|CONST}} CURSOR_RIGHT_LEFT_CORNER = {{Text|17|#F580B1}}
{{Cl|CONST}} CURSOR_MOVE = {{Text|5|#F580B1}}
{{Cl|CONST}} CURSOR_NONE = {{Text|23|#F580B1}}
 
{{Cl|DECLARE LIBRARY}}
{{Cl|DECLARE LIBRARY}}
  {{Cl|SUB}} SDL_WarpMouse ({{Cl|BYVAL}} column {{Cl|AS}} {{Cl|LONG}}, {{Cl|BYVAL}} row {{Cl|AS}} {{Cl|LONG}}) 'SDL procedure name
    {{Cl|SUB}} {{Text|glutSetCursor|#55FF55}} ({{Cl|BYVAL}} style&)
{{Cl|DECLARE LIBRARY|END DECLARE}}
{{Cl|END DECLARE}}
{{Cl|SCREEN (statement)|SCREEN}} {{Cl|_NEWIMAGE}}(640, 480, 256)  'simulate screen 12 with 256 colors
{{Cl|RANDOMIZE}} {{Cl|TIMER}}


DO
{{Text|glutSetCursor|#55FF55}} CURSOR_CROSSHAIR
  {{Cl|_DELAY}} 1
{{CodeEnd}}
  x = {{Cl|RND}} * 640: y = {{Cl|RND}} * 480
  {{Cl|LINE}} (x, y)-{{Cl|STEP}}(10, 10), {{Cl|RND}} * 100 + 32, BF
  MouseMove x + 5, y + 5
{{Cl|LOOP}} {{Cl|UNTIL}} {{Cl|LEN}}({{Cl|INKEY$}})  'any keypress quits
{{Cl|END}}


{{Cl|SUB}} MouseMove (x {{Cl|AS}} {{Cl|LONG}}, y {{Cl|AS}} {{Cl|LONG}})
SDL_WarpMouse x, y    'call SDL library procedure
{{Cl|END SUB}} '' ''
{{CodeEnd}}
{{small|Code by Galleon}}
:''Explanation:'' The SDL Library is included and loaded with QB64 versions prior to 1.000, so these procedures are directly available for use.


<center>'''Using [[ALIAS]] to create a program SUB or FUNCTION''' using '''QB64 SDL ONLY'''</center>
;Example 2: Using [[ALIAS]] to create a program SUB or FUNCTION'''.
{{CodeStart}} '' ''
{{CodeStart}}
{{Cl|SCREEN}} 12
{{Cl|DECLARE LIBRARY}}
{{Cl|DECLARE LIBRARY}}
  {{Cl|SUB}} MouseMove {{Cl|ALIAS}} SDL_WarpMouse ({{Cl|BYVAL}} column&, {{Cl|BYVAL}} row&)
    {{Cl|FUNCTION}} {{Text|GetMilliseconds~&&|#55FF55}} {{Cl|ALIAS}} GetTicks
{{Cl|DECLARE LIBRARY|END DECLARE}}
{{Cl|END DECLARE}}


{{Cl|_DELAY}} 2
{{Cl|DO}}
MouseMove 100, 100
    {{Cl|LOCATE}} , {{Text|1|#F580B1}}: {{Cl|PRINT}} {{Text|<nowiki>"Seconds since program start:"</nowiki>|#FFB100}}; {{Text|GetMilliseconds|#55FF55}} \ {{Text|1000|#F580B1}};
{{Cl|_DELAY}} 2
{{Cl|DO...LOOP|LOOP UNTIL}} {{Cl|_KEYHIT}} = {{Text|27|#F580B1}}
MouseMove 200, 200 '' ''
{{CodeEnd}}
{{CodeEnd}}
:''Explanation:'' When a Library procedure is used to represent another procedure name use [[ALIAS]] instead. Saves creating a SUB!
:''Explanation:'' When a library procedure is used to represent another procedure name use [[ALIAS]] instead. Saves creating a SUB!




''Example 2:'' Don't know if a C function is defined by C++ or QB64? Try using empty quotes.
;Example 3: Don't know if a C function is defined by C++ or QB64? Try using empty quotes.
{{CodeStart}} '' ''
{{CodeStart}}
{{Cl|DECLARE LIBRARY}} ""
{{Cl|DECLARE LIBRARY}} {{Text|<nowiki>""</nowiki>|#FFB100}}
     {{Cl|FUNCTION}} addone& ({{Cl|BYVAL}} value&)
     {{Cl|FUNCTION}} {{Text|addone&|#55FF55}} ({{Cl|BYVAL}} value&)
{{Cl|END}} DECLARE '' ''
{{Cl|END DECLARE}}
{{CodeEnd}}
{{CodeEnd}}
:''Explanation:'' The C function 'addone' exists in a library QB64 already links to, but it hasn't been defined as a C function or a QB64 function. By using "" we are telling QB64 the function exists in a library which is already linked to and that it must define the C function before calling it, as well as allowing QB64 code to call it. Trying the above code without the "" will fail.
:''Explanation:'' The C function 'addone' exists in a library QB64 already links to, but it hasn't been defined as a C function or a QB64 function. By using "" we are telling QB64 the function exists in a library which is already linked to and that it must define the C function before calling it, as well as allowing QB64 code to call it. Trying the above code without the "" will fail.


: '''Note: What libraries are or aren't automatically used in the linking process is not formally defined, nor is it guaranteed to stay that way in future versions of QB64.'''


;Example 4: This example plays MIDI files using the ''playmidi32.dll'' documented here: [http://libertybasicuniversity.com/lbnews/nl110/midi3.htm Liberty Basic University]. Download the following DLL file to your main QB64 directory: [https://www.qb64.org/resources/Playmidi32.dll PlayMidi32.dll]
{{CodeStart}}
{{Cl|DECLARE}} {{Cl|DYNAMIC}} {{Cl|LIBRARY}} {{Text|<nowiki>"playmidi32"</nowiki>|#FFB100}}
    {{Cl|FUNCTION}} {{Text|PlayMIDI&|#55FF55}} (filename {{Cl|AS}} {{Cl|STRING}})
{{Cl|END DECLARE}}
result = {{Text|PlayMIDI|#55FF55}}({{Text|<nowiki>".\samples\qb64\original\ps2battl.mid"</nowiki>|#FFB100}} + {{Cl|CHR$}}({{Text|0|#F580B1}}))
{{Cl|PRINT}} result
{{CodeEnd}}
;Example 5: Using a CUSTOMTYPE LIBRARY to return the [[Unicode]] version of the current running program's name.
{{CodeStart}}
{{Cl|SCREEN}} {{Text|12|#F580B1}}
{{Cl|DECLARE}} {{Cl|CUSTOMTYPE}} {{Cl|LIBRARY}} {{Text|<nowiki>'Directory Information using KERNEL32 provided by Dav</nowiki>|#919191}}
    {{Cl|FUNCTION}} {{Text|GetModuleFileNameA&|#55FF55}} ({{Cl|BYVAL}} hModule {{Cl|AS}} {{Cl|LONG}}, lpFileName {{Cl|AS}} {{Cl|STRING}}, {{Cl|BYVAL}} nSize {{Cl|AS}} {{Cl|LONG}})
    {{Cl|FUNCTION}} {{Text|GetModuleFileNameW&|#55FF55}} ({{Cl|BYVAL}} hModule {{Cl|AS}} {{Cl|LONG}}, lpFileName {{Cl|AS}} {{Cl|STRING}}, {{Cl|BYVAL}} nSize {{Cl|AS}} {{Cl|LONG}})
{{Cl|END DECLARE}}
{{Text|<nowiki>'=== SHOW CURRENT PROGRAM</nowiki>|#919191}}
FileName$ = {{Cl|SPACE$}}({{Text|512|#F580B1}})
Result = {{Text|GetModuleFileNameA|#55FF55}}({{Text|0|#F580B1}}, FileName$, {{Cl|LEN}}(FileName$))
{{Cl|IF}} Result {{Cl|THEN}} {{Cl|PRINT}} {{Text|<nowiki>"CURRENT PROGRAM (ASCII): "</nowiki>|#FFB100}}; {{Cl|LEFT$}}(FileName$, Result)
{{Text|<nowiki>'load a unicode font</nowiki>|#919191}}
f = {{Cl|_LOADFONT}}({{Text|<nowiki>"cyberbit.ttf"</nowiki>|#FFB100}}, {{Text|24|#F580B1}}, {{Text|<nowiki>"UNICODE"</nowiki>|#FFB100}})
{{Cl|_FONT}} f
Result = {{Text|GetModuleFileNameW|#55FF55}}({{Text|0|#F580B1}}, FileName$, {{Cl|LEN}}(FileName$) \ {{Text|2|#F580B1}})
{{Cl|LOCATE}} {{Text|2|#F580B1}}, {{Text|1|#F580B1}}
{{Cl|PRINT}} {{Text|QuickCP437toUTF32$|#55FF55}}({{Text|<nowiki>"CURRENT PROGRAM (UTF): "</nowiki>|#FFB100}}) + {{Text|QuickUTF16toUTF32$|#55FF55}}({{Cl|LEFT$}}(FileName$, Result * {{Text|2|#F580B1}}))
{{Cl|_FONT}} {{Text|16|#F580B1}} {{Text|<nowiki>'restore CP437 font</nowiki>|#919191}}
{{Cl|FUNCTION}} {{Text|QuickCP437toUTF32$|#55FF55}} (a$)
    b$ = {{Cl|STRING$}}({{Cl|LEN}}(a$) * {{Text|4|#F580B1}}, {{Text|0|#F580B1}})
    {{Cl|FOR}} i = {{Text|1|#F580B1}} {{Cl|TO}} {{Cl|LEN}}(a$)
        {{Cl|ASC}}(b$, i * {{Text|4|#F580B1}} - {{Text|3|#F580B1}}) = {{Cl|ASC (function)|ASC}}(a$, i)
    {{Cl|NEXT}}
    {{Text|QuickCP437toUTF32$|#55FF55}} = b$
{{Cl|END FUNCTION}}
{{Cl|FUNCTION}} {{Text|QuickUTF16toUTF32$|#55FF55}} (a$)
    b$ = {{Cl|STRING$}}({{Cl|LEN}}(a$) * {{Text|2|#F580B1}}, {{Text|0|#F580B1}})
    {{Cl|FOR}} i = {{Text|1|#F580B1}} {{Cl|TO}} {{Cl|LEN}}(a$) \ {{Text|2|#F580B1}}
        {{Cl|ASC}}(b$, i * {{Text|4|#F580B1}} - {{Text|3|#F580B1}}) = {{Cl|ASC (function)|ASC}}(a$, i * {{Text|2|#F580B1}} - {{Text|1|#F580B1}})
        {{Cl|ASC}}(b$, i * {{Text|4|#F580B1}} - {{Text|2|#F580B1}}) = {{Cl|ASC (function)|ASC}}(a$, i * {{Text|2|#F580B1}})
    {{Cl|NEXT}}
    {{Text|QuickUTF16toUTF32$|#55FF55}} = b$
{{Cl|END FUNCTION}}
{{CodeEnd}}
{{Small|Code by Galleon}}


<center>'''QB64 version 1.000 and up produce standalone executables. External DLL files must be distributed with your program.'''</center>
<center>'''Note: QB64 versions prior to 1.000 require all default DLL files to either be with the program or in the C:\WINDOWS\SYSTEM32 folder.'''</center>




''See also:''
{{PageSeeAlso}}
* [[DECLARE DYNAMIC LIBRARY]]
* [[SUB]], [[FUNCTION]]
* [[SUB]], [[FUNCTION]]
* [[BYVAL]], [[ALIAS]]
* [[BYVAL]], [[ALIAS]]
* [[_OFFSET (function)]], [[_OFFSET]] {{Text|(variable type)}}
* [[C Libraries]], [[DLL Libraries]], [[Windows Libraries]]
* [[C Libraries]], [[DLL Libraries]], [[Windows Libraries]]
* [[Port Access Libraries]]
* [[Port Access Libraries]]

Latest revision as of 20:17, 8 March 2024

The DECLARE LIBRARY declaration allows for the utilization of external library SUB and FUNCTION procedures.


Syntax

DECLARE [DYNAMIC|CUSTOMTYPE|STATIC] LIBRARY ["Library_name"][, "Library_name2"][, ...]
{SUB|FUNCTION} Procedure_name [ALIAS Library_procedure] (BYVAL Parameter[{suffix| AS type[, Parameter2...][, ...]])
.
. ' Other SUBs or FUNCTIONs as required
.
END DECLARE


Description

  • The declaration can be used with:
    • C/C++ sub-procedures files (.h and .hpp)
    • Dynamically linked libraries and shared object files (.dll, .so and .dylib)
    • Static libraries (.a)
    • Object files (.o)
  • Library file names can be listed to combine more than one supported file name or path into one DECLARE LIBRARY block (except for dynamically linked libraries and shared object files). Do not include any file extension (.h, .dll, .a etc.).
  • The dynamically linked library or shared object file can be in a relative/absolute path specified along with the library name, in the operating system's directory (e.g., C:\Windows\System32), or in the QB64 directory (alongside your program's executable).
  • Specify "" as the library file name to inform QB64 that the function exists in a library that is already linked and that it must define the C function before calling it, as well as allowing QB64 code to call it.
  • It's a good idea to try declaring Operating System API libraries without a library file name first, as most common Operating System headers are already included in QB64 source.
  • When using a procedure from a dynamically linked library or shared object (.dll, .so and .dylib files) use DECLARE DYNAMIC LIBRARY.
  • When using a procedure from a static library (.a files) use DECLARE STATIC LIBRARY.
  • Procedure_name can be any desired procedure name designated by using ALIAS with the Library_procedure name following. Enclose Library_procedure in "" when using a C++ function with the scope operator (e.g., "std::clamp").
  • Parameters used by the library procedure can be passed by value (BYVAL) when needed, except for STRING values.
  • QB64 STRINGs are passed to external libraries as pointers to first character. Many external library procedures expect strings to be NULL terminated. Terminate STRINGs using CHR$(0) wherever it is needed.
  • Declarations can be made inside of SUB or FUNCTION procedures. Declarations do not need to be at program start.
  • C/C++ procedures can use a header file name and the file code must be included with program code.
  • C/C++ header files cannot be used with DECLARE DYNAMIC LIBRARY. Existence of any .h or .hpp file of the same name as the dynamically linked library or shared object file will cause DECLARE DYNAMIC LIBRARY to fail.
  • The _OFFSET in memory can be used in CUSTOMTYPE, STATIC and DYNAMIC LIBRARY declarations.
  • DECLARE DYNAMIC LIBRARY let's you specify any SUB/FUNCTION calling format you wish, but if the size of the parameters does not match, the size expected within the library, your code will probably cause a GPF (General Protection Fault). It is important to understand that pointers (if required) will be 32-bits in size (the equivalent of a LONG) when creating a 32-bit program (even under 64-bit Windows).
  • STATIC is the same as DYNAMIC except that it prioritizes linking to static libraries (.a and .o files) over dynamically linked libraries and shared object files, if both exist.
  • CUSTOMTYPE is already implied when using DECLARE DYNAMIC LIBRARY. This type of library just allows the same flexibility to apply when referencing STATIC libraries that are used to refer to dynamic libraries.
  • SUB procedures using DECLARE CUSTOMTYPE LIBRARY API procedures may error. Try DYNAMIC with the dynamically linked library or shared object file name.
  • It is up to the user to document and determine the suitability of all libraries and procedures they choose to use. QB64 cannot guarantee that any procedure will work and cannot guarantee any troubleshooting help.
  • QB64 version 1.000 and up produce standalone executables. External dynamically linked libraries or shared object files must be distributed with your program.
  • What libraries are or aren't automatically used in the linking process is not formally defined, nor is it guaranteed to stay that way in future versions of QB64.


Parameters

  • The Library_name is needed if a library is not already loaded by QB64. Do not include the file extension. Begin the Library_name with ./ or .\ to make it relative to the path where your source file is saved, so you can keep all your project files together.
  • Procedure_name is any program procedure name you want to designate by using ALIAS with the Library_procedure name.
  • Library procedure is the actual procedure name used inside of the library or header file.


Availability

  • Available for Linux and macOS since QB64 v0.940


Examples

Example 1
Using GLUT library procedure as a program SUB procedure to set the mouse pointer style.
CONST CURSOR_NORMAL = 1
CONST CURSOR_HAND = 2
CONST CURSOR_HELP = 4
CONST CURSOR_CYCLE = 7
CONST CURSOR_TEXT = 8
CONST CURSOR_CROSSHAIR = 3
CONST CURSOR_UP_DOWN = 10
CONST CURSOR_LEFT_RIGHT = 11
CONST CURSOR_LEFT_RIGHT_CORNER = 16
CONST CURSOR_RIGHT_LEFT_CORNER = 17
CONST CURSOR_MOVE = 5
CONST CURSOR_NONE = 23

DECLARE LIBRARY
    SUB glutSetCursor (BYVAL style&)
END DECLARE

glutSetCursor CURSOR_CROSSHAIR


Example 2
Using ALIAS to create a program SUB or FUNCTION.
DECLARE LIBRARY
    FUNCTION GetMilliseconds~&& ALIAS GetTicks
END DECLARE

DO
    LOCATE , 1: PRINT "Seconds since program start:"; GetMilliseconds \ 1000;
LOOP UNTIL _KEYHIT = 27
Explanation: When a library procedure is used to represent another procedure name use ALIAS instead. Saves creating a SUB!


Example 3
Don't know if a C function is defined by C++ or QB64? Try using empty quotes.
DECLARE LIBRARY ""
    FUNCTION addone& (BYVAL value&)
END DECLARE
Explanation: The C function 'addone' exists in a library QB64 already links to, but it hasn't been defined as a C function or a QB64 function. By using "" we are telling QB64 the function exists in a library which is already linked to and that it must define the C function before calling it, as well as allowing QB64 code to call it. Trying the above code without the "" will fail.


Example 4
This example plays MIDI files using the playmidi32.dll documented here: Liberty Basic University. Download the following DLL file to your main QB64 directory: PlayMidi32.dll
DECLARE DYNAMIC LIBRARY "playmidi32"
    FUNCTION PlayMIDI& (filename AS STRING)
END DECLARE
result = PlayMIDI(".\samples\qb64\original\ps2battl.mid" + CHR$(0))
PRINT result


Example 5
Using a CUSTOMTYPE LIBRARY to return the Unicode version of the current running program's name.
SCREEN 12

DECLARE CUSTOMTYPE LIBRARY 'Directory Information using KERNEL32 provided by Dav
    FUNCTION GetModuleFileNameA& (BYVAL hModule AS LONG, lpFileName AS STRING, BYVAL nSize AS LONG)
    FUNCTION GetModuleFileNameW& (BYVAL hModule AS LONG, lpFileName AS STRING, BYVAL nSize AS LONG)
END DECLARE

'=== SHOW CURRENT PROGRAM
FileName$ = SPACE$(512)

Result = GetModuleFileNameA(0, FileName$, LEN(FileName$))
IF Result THEN PRINT "CURRENT PROGRAM (ASCII): "; LEFT$(FileName$, Result)

'load a unicode font
f = _LOADFONT("cyberbit.ttf", 24, "UNICODE")
_FONT f
Result = GetModuleFileNameW(0, FileName$, LEN(FileName$) \ 2)
LOCATE 2, 1
PRINT QuickCP437toUTF32$("CURRENT PROGRAM (UTF): ") + QuickUTF16toUTF32$(LEFT$(FileName$, Result * 2))
_FONT 16 'restore CP437 font

FUNCTION QuickCP437toUTF32$ (a$)
    b$ = STRING$(LEN(a$) * 4, 0)
    FOR i = 1 TO LEN(a$)
        ASC(b$, i * 4 - 3) = ASC(a$, i)
    NEXT
    QuickCP437toUTF32$ = b$
END FUNCTION

FUNCTION QuickUTF16toUTF32$ (a$)
    b$ = STRING$(LEN(a$) * 2, 0)
    FOR i = 1 TO LEN(a$) \ 2
        ASC(b$, i * 4 - 3) = ASC(a$, i * 2 - 1)
        ASC(b$, i * 4 - 2) = ASC(a$, i * 2)
    NEXT
    QuickUTF16toUTF32$ = b$
END FUNCTION
Code by Galleon


See also



Navigation:
Main Page with Articles and Tutorials
Keyword Reference - Alphabetical
Keyword Reference - By usage
Report a broken link