[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