[openal] ALC_NO_PROTOTYPES in alc.h / loading function pointers
Chris Robinson
chris.kcat at gmail.com
Thu Aug 11 21:31:41 EDT 2016
On 08/11/2016 12:33 PM, Felix Patschkowski wrote:
> Hi,
>
> I've recently installed the OpenAL SDK 1.1 to do some audio programming.
> Having an OpenGL/Vulkan background I'm used to load function pointers from
> DLL myself.
>
> al.h provides AL_NO_PROTOTYPES to not declare al* prototypes, why is there
> no ALC_NO_PROTOTYPES for alc.h?
I'm actually not too sure why there's an AL_NO_PROTOTYPES macro. I
suppose to just make super extra sure you don't accidentally use AL
functions directly? I don't understand why it determines if you get the
function typedefs or not, either (just because the functions are
declared doesn't mean the typedefs can't be defined too).
If you're loading the standard functions dynamically, it would be a good
idea to not name your function pointers the same as the real functions
anyway. Some systems use global space for the symbols in a process, so
if your app defines a particular symbol name and you load a lib that
exports the same symbol name (even if it's a different type), bad things
can happen. Linux can fall prey to this, although does have controls to
hide and/or protect symbols to prevent them from getting mixed up.
The way I handle things like this is to define a function pointer and
use a macro to override the original with it. Like:
__typeof(alFunc) *p_alFunc;
#define alFunc p_alFunc
So you can call alFunc in your code as normal, which is really p_alFunc,
which you previously loaded with the real alFunc address. If you're
dynamically loading the lib with LoadLibrary/dlopen, you'll get a linker
error if you accidentally used a function directly.
> Which approach is considered best practice: Loading all function pointers
> using GetProcAddress/dlsym or only loading al*GetProcAddress with
> GetProcAddress/dlsym and using al*GetProcAddress to retrieve the remaining
> function pointers?
I would say load all standard functions with GetProcAddress/dlsym since
they're standard exports, and any extension functions (such as from EFX)
should use al[c]GetProcAddress since they may be driver-dependent exports.
> The SDK sample uses the first approach. The OpenAL Deployment Guide
> mentions the "OpenAL router". Would it be possible to bypass the router
> using the seond approach?
From the looks of it, the router's al[c]GetProcAddress will return its
own functions, and only return the driver's when it doesn't recognize it
(and which will not work for returned alc functions since the router
wraps the driver's device handle into its own; so you can get a driver's
alc extension function, but it won't recognize any device or context you
pass to it since they're the router's).
If I ever do write a new router, this will certainly be among the things
I want to fix. A lightweight dispatch table for al calls on the current
context, and passing back the device and context handles as-is from the
driver, using lookup tables to pair those handles to any extra
information needed about them.
More information about the openal
mailing list