Re: [LAD] jack for windows compared to linux

From: Stéphane Letz <letz@email-addr-hidden>
Date: Mon Jun 01 2009 - 17:28:26 EEST

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

> Stéphane Letz <letz@email-addr-hidden> writes:
>
>> Le 1 juin 09 à 15:23, Nedko Arnaudov a écrit :
>>
>>> Stéphane Letz <letz@email-addr-hidden> 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
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/mailman/listinfo/linux-audio-dev
Received on Mon Jun 1 20:15:02 2009

This archive was generated by hypermail 2.1.8 : Mon Jun 01 2009 - 20:15:02 EEST