[LAD] jack for windows compared to linux

Stéphane Letz letz at grame.fr
Mon Jun 1 14:28:26 UTC 2009


Le 1 juin 09 à 16:05, Nedko Arnaudov a écrit :

> Stéphane Letz <letz at grame.fr> writes:
>
>> Le 1 juin 09 à 15:23, Nedko Arnaudov a écrit :
>>
>>> Stéphane Letz <letz at grame.fr> writes:
>>>
>>>>> What do you think Stephane, can native jack clients on windows
>>>>> achieve
>>>>> performance which is almost at par as native ASIO apps ?
>>>>> If we release LinuxSampler with jack support we have probably to
>>>>> ship
>>>>> libjack (otherwise the app does not start)  with the sampler  
>>>>> and it
>>>>> could be that it conflicts with an
>>>>> already installed jack.
>>>>
>>>> Well I also recently had this kind of "weak" link requirement for
>>>> libjack on Linux. I think OSX supports some kind of weak linking  
>>>> with
>>>> any compiled framework, but the situation is less clear on  
>>>> Windows on
>>>> Linux. A possible solution would be to provide a special
>>>> "libweakjack" library with the appropriate bahaviour for that.
>>>
>>> On Windows, you can use LoadLibrary() API function to load
>>> libjack.dll.
>>> On Linux, dlopen() can be used to load libjack.so.
>>>
>>
>> Yes, but with what library do you link your code? AFACS the point is
>> that if libjack.so is missing, then the application does not start...
>> if no weak link strategy is used.
>
> You dont link at all. You have to explicitly load the libarary and
> resolve functions in it. I.e. like filling method pointers in the
> virtual table of object of abstract class.
>

Yep, but the point is to avoid having to do that "each time" by  
providing something like:

/* dynamically load libjack and forward all registered calls to libjack
    (similar to what relaytool is trying to do, but more portably..)
*/

using std::cerr;

int libjack_is_present = 0;     // public symbol, similar to what  
relaytool does.
static void *libjack_handle = 0;

static void __attribute__((constructor)) tryload_libjack()
{
     if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is  
causing troubles..
         libjack_handle = dlopen("libjack.so.0", RTLD_LAZY);
     }
     libjack_is_present = (libjack_handle != 0);
}

void *load_jack_function(const char *fn_name)
{
     void *fn = 0;
     if (!libjack_handle) {
         std::cerr << "libjack not found, so do not try to load " <<  
fn_name << " ffs !\n";
         return 0;
     }
     fn = dlsym(libjack_handle, fn_name);
     if (!fn) {
         std::cerr << "could not dlsym(" << libjack_handle << "), "  
<< dlerror() << "\n";
     }
     return fn;
}

#define DECL_FUNCTION(return_type, fn_name, arguments_types,  
arguments) \
   typedef return_type (*fn_name##_ptr_t) 
arguments_types;                \
   return_type fn_name arguments_types  
{                                 \
     static fn_name##_ptr_t fn =  
0;                                      \
     if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function 
(#fn_name); } \
     if (fn) return (*fn) 
arguments;                                      \
     else return  
0;                                                      \
   }

#define DECL_VOID_FUNCTION(fn_name, arguments_types,  
arguments)         \
   typedef void (*fn_name##_ptr_t) 
arguments_types;                       \
   void fn_name arguments_types  
{                                        \
     static fn_name##_ptr_t fn =  
0;                                      \
     if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function 
(#fn_name); } \
     if (fn) (*fn) 
arguments;                                             \
   }

DECL_FUNCTION(jack_client_t *, jack_client_open, (const char  
*client_name, jack_options_t options, jack_status_t *status, ...),
               (client_name, options, status));
DECL_FUNCTION(int, jack_client_close, (jack_client_t *client),  
(client));
.....

Then the previous code can be compiled with the application which  
just need to test the symbol before using it. (Or it could maybe be   
compiled as a static lib..)

What could be done is to distribute this file as part of JACK packge,  
or as a static lib.

Stephane 


More information about the Linux-audio-dev mailing list