DECLARE DYNAMIC LIBRARY

From QB64 Wiki
Revision as of 15:54, 17 April 2019 by imported>Odin
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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.


Syntax

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


Description

  • 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 filenames 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 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 you are creating a 32-bit program (even under 64-bit Windows) so pointers (if required) will be 32-bits in size, the equivalent of a LONG.
  • 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.


Availability

  • Version 0.923 and up (Windows)
  • Version 0.94 and up (Linux and macOS)


Examples

Example 1: This example plays Midi files using the playmidi32.dll documented here: Liberty Basic University. Download the following DLL file to your main QB64 folder: PlayMidi32.dll

DECLARE DYNAMIC LIBRARY "playmidi32" FUNCTION PlayMIDI& (filename AS STRING) END DECLARE result = PlayMIDI(".\samples\qb64\original\ps2battl.mid" + CHR$(0)) PRINT result

Note: Filename needs to be CHR$(0) terminated. QB64 STRINGs 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.

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
Note: SUB procedures using CUSTOMTYPE LIBRARY API procedures inside may error. Try DYNAMIC with "KERNEL32".


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


See also:



Navigation:
Go to Keyword Reference - Alphabetical
Go to Keyword Reference - By usage
Go to Main WIKI Page