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