'''DECLARE DYNAMIC LIBRARY''' allows you to dynamically link your program to functions in dynamically linkable libraries. At present, only ''.DLL'' files are supported (support for ''.so'' will be added soon). These libraries are loaded when your program begins.


{{PageSyntax}}
: DECLARE [DYNAMIC|CUSTOMTYPE|STATIC] LIBRARY [''"DLL_Library_file"'', "other_library..."]
: {SUB|FUNCTION} [''procedure_name'' ALIAS] ''library_procedure'' (BYVAL ''parameter(s)'',...)
::.
::. 'other Library sub-procedures for named ''DLL''
::.
: END DECLARE


{{PageDescription}}
* The dynamic library file can be located in the QB64 folder (alongside your programs '.EXE'), in Windows' system32 folder, or in a relative/absolute path specified along with the library name.
* '''Declarations must be made at the program start and only one ''.DLL'' file can be specified in each declaration block.'''
* ''Library_file'' is the ''DLL'' file's name with a specified path when not in the QB64 or the WINDOWS\SYSTEM32 folder. Don't add a file extension.
* ''Library filename''s can be listed to combine more than one DLL or Header file name or path into one DECLARE LIBRARY block.
* ''Procedure_name'' is any procedure name you want to designate by using [[ALIAS]] with the ''Library_procedure'' name following. 
* ''Parameters'' used by the Library procedure must be passed by value ([[BYVAL]]) except for [[STRING]] values.
* '''''.h'' header files cannot be used with DECLARE DYNAMIC LIBRARY. Existence of any ''.h'' file of the same name as the ''.DLL'' file will cause DECLARE DYNAMIC LIBRARY to fail.'''
* '''IMPORTANT:''' [[DECLARE DYNAMIC LIBRARY]] let's you specify any SUB/FUNCTION calling with the format you wish, but '''if the size of the parameter list does not match the size expected within the library, then your code will probably cause a GPF (General Protection Fault).
* '''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 really use shared libraries (DLLs are a bit different) this does not affect Windows users.
* The [[_OFFSET]] in memory can be used in '''CUSTOMTYPE''', '''STATIC''' and '''DYNAMIC LIBRARY''' declarations.
* [[SUB]] procedures using DECLARE CUSTOMTYPE LIBRARY API procedures '''may error'''. Try DYNAMIC with the DLL name.
* Declarations can be made inside of [[SUB]] or [[FUNCTION]] procedures. Declarations do not need to be at program start.
* '''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.'''


{{PageAvailability}}
* Version 0.923 and up (Windows).
* Version 0.94 and up (Linux and macOS).


{{PageExamples}}
''Example 1:'' 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 folder: [https://www.qb64.org/resources/Playmidi32.dll PlayMidi32.dll]
{{CodeStart}} '' ''
{{Cl|DECLARE DYNAMIC LIBRARY}} "playmidi32"
    {{Cl|FUNCTION}} PlayMIDI&amp; (filename {{Cl|AS}} {{Cl|STRING}})
{{Cl|DECLARE LIBRARY|END DECLARE}}
result = PlayMIDI(".\samples\qb64\original\ps2battl.mid" + {{Cl|CHR$}}(0))
{{Cl|PRINT}} result
{{CodeEnd}}
: '''Note:''' Filename needs to be [[CHR$]](0) terminated. QB64 [[STRING]]s are passed to external libraries as pointers to first character.


''Example 2:'' Using a CUSTOMTYPE LIBRARY to return the [[Unicode]] version of the current running program's name.
{{CodeStart}} '' ''
{{Cl|SCREEN}} 12

{{Cl|DECLARE DYNAMIC LIBRARY|DECLARE CUSTOMTYPE LIBRARY}} 'Directory Information using KERNEL32 provided by Dav
    {{Cl|FUNCTION}} GetModuleFileNameA&amp; ({{Cl|BYVAL}} hModule {{Cl|AS}} {{Cl|LONG}}, lpFileName {{Cl|AS}} {{Cl|STRING}}, {{Cl|BYVAL}} nSize {{Cl|AS}} {{Cl|LONG}})
    {{Cl|FUNCTION}} GetModuleFileNameW&amp; ({{Cl|BYVAL}} hModule {{Cl|AS}} {{Cl|LONG}}, lpFileName {{Cl|AS}} {{Cl|STRING}}, {{Cl|BYVAL}} nSize {{Cl|AS}} {{Cl|LONG}})
{{Cl|DECLARE LIBRARY|END DECLARE}}

'=== SHOW CURRENT PROGRAM
FileName$ = {{Cl|SPACE$}}(512)

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

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

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

{{Cl|FUNCTION}} QuickUTF16toUTF32$ (a$)
b$ = {{Cl|STRING$}}({{Cl|LEN}}(a$) * 2, 0)
{{Cl|FOR...NEXT|FOR}} i = 1 {{Cl|TO}} {{Cl|LEN}}(a$) \ 2
    {{Cl|ASC}}(b$, i * 4 - 3) = {{Cl|ASC}}(a$, i * 2 - 1)
    {{Cl|ASC}}(b$, i * 4 - 2) = {{Cl|ASC}}(a$, i * 2)
{{Cl|NEXT}}
QuickUTF16toUTF32$ = b$
{{Cl|END FUNCTION}} '' ''
{{CodeEnd}}
{{small|Code by Galleon}} 
: '''Note:''' SUB procedures using CUSTOMTYPE LIBRARY API procedures inside may error. Try DYNAMIC with "KERNEL32".


&lt;center>'''QB64 version 1.000 and up produce standalone executables. External DLL files must be distributed with your program.'''&lt;/center>
&lt;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.'''&lt;/center>


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


{{PageNavigation}}
