Hi Jack,
C/C++ header files are included into the program by defining a DECLARE LIBRARY function block. Taking my qbstdarg library as example you see there are 3 files, qbstdarg.h, qbstdarg.bi and qbstdarg.bm, which together built up the library.
As usual you've to $INCLUDE the .bi file at the beginning of a program and the .bm at the end. The .bi file usually contains required declarations such as CONST, DIM or DIM SHARED variables, TYPE defines and in this case DECLARE LIBRARY blocks, while the .bm file contains the SUBs and FUNCTIONs you later use in the program.
If you now take a look into qbstdarg.bi, then you will notice the DECLARE LIBRARY block which specifies the name of the C/C++ header file (but the path/name only without the actual .h extension) and within the block all subroutines/functions contained in the C/C++ are declared, so that QB64 knows how to call these functions. In general this is similar to using WinAPI calls or 3rd party .dll files, just instead of the name of a WinAPI/DLL (eg. kernel32) you specify the C/C++ header name. As you can also add a path here, there's no need to keep header files in a certain folder, just make sure your path is correct (best relative to the qb64 folder, if you wanna keep libraries in its own project folder inside the qb64 folder, as i do). With the function declarations inside the DECLARE LIBRARY block just make sure to use the right QB64 variable types for the result and arguments used in the C/C++ functions:
_BYTE (%%) = char or int8, _UNSIGNED _BYTE (~%%) = uchar or uint8
INTEGER (%) = int16, _UNSIGNED INTEGER (~%) = uint16
LONG (&) = int32, _UNSIGNED LONG (~&) = uint32
_INTEGER64 (&&) = int64, _UNSIGNED _INTEGER64 (~&&) = uint64
SINGLE (!) = float (don't get confused with QB64 _FLOAT here)
DOUBLE(#) = double
_FLOAT (##) = long double (not 100% sure here)
all these must be passed BYVAL, STRING and arrays otherwise are passed as reference, hence pointers (ie. without BYVAL). In C/C++ function argument lists you best use "ptrszint" for those arguments to automatically support 32/64 bit environments. However, you might need to cast the ptrszint into some real datatype in C/C++ to be able to work with it (eg: char* myString = (char*) givenStrArg, if the argument was declared like this in the header: myFunc(ptrszint givenStrArg) {.... code of the function ....}). Well, this is for selfmade strings (dynamically allocated within the header using malloc(), for real QB64 strings it's easier, as QB64 already know about its pointer and the compiler does the magic for 32/64 bits. A real STRING can be passed as is in C/C++
(eg. myFunc(char* givenStArg) .
Guess some questions are cleared now, but a lot more will arise now :), maybe if you're tell me what you're about to do, i can give some more specific details how to accomplish your goal.