機能する解決策を見つけました...呼び出しをサードパーティ ライブラリにリダイレクトするシム ライブラリを作成し、ライブラリ外のコードが protbuf v2.4 シンボルを参照できるようにし、サードパーティ ライブラリ内のコードが protobuf v2.3 シンボルを参照できるようにしました。この回避策は、 http ://www.linuxjournal.com/article/7795 に投稿されたアイデアに基づいています。
RTLD_LAZY | を含めるように dlopen フラグを変更する必要がありました。RTLD_LOCAL | RTLD_DEEPBIND. RTLD_LOCAL フラグは、サードパーティ ライブラリ内のシンボルが shim ライブラリの外部に表示されないようにします (シンボルの漏洩を防ぎます)。RTLD_DEEPBIND は、サードパーティ ライブラリ内からの呼び出しに、シンボルの内部バージョンのみを表示するように強制します (シンボルが漏れないようにします)。
具体的には、これが私の shim ライブラリからの抜粋の例です。
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include "libhdfs/hdfs.h"
//#define PRINT_DEBUG_STUFF
// Helper function to retrieve a function pointer to a function from libMapRClient
// while isolating the symbols used internally from those already linked externaly
// to workaround symbol collision problem with the current version of libMapRClient.
void* GetFunc(const char* name){
#ifdef PRINT_DEBUG_STUFF
printf("redirecting %s\n", name);
#endif
void *handle;
char *error;
handle = dlopen("/opt/mapr/lib/libMapRClient.so", RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
if (!handle) {
fputs(dlerror(), stderr);
exit(1);
}
void* fp = dlsym(handle, name);
if ((error = dlerror()) != 0) {
fprintf(stderr, "%s\n", error);
exit(1);
}
return fp;
}
hdfsFS hdfsConnect(const char* host, tPort port) {
typedef hdfsFS (*FP) (const char* host, tPort port);
static FP ext = 0;
if (!ext) {
ext = (FP)GetFunc("hdfsConnect");
}
return ext(host, port);
}
int hdfsCloseFile(hdfsFS fs, hdfsFile file) {
typedef int (*FP) (hdfsFS fs, hdfsFile file);
static FP ext = 0;
if (!ext) {
ext = (FP)GetFunc("hdfsCloseFile");
}
return ext(fs, file);
}
... その他のパブリック API 関数についても同様