Le 1 juin 09 à 16:05, Nedko Arnaudov a écrit :
Stéphane Letz <letz(a)grame.fr> writes:
Le 1 juin 09 à 15:23, Nedko Arnaudov a écrit :
Stéphane Letz <letz(a)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