2

特定の自己記述ライブラリを使用して、または使用せずにアプリケーション実行できるコードが必要です。そのため、必要に応じてライブラリを使用してプリロードします。再コンパイルせずにそれを行うことができる必要があります。ただし、ライブラリを静的にリンクすると、すべて正常に動作します。__attribute__ ((weak))

さらに、ライブラリは C++ で記述されていますが、それを使用するアプリケーションは C++ または C にすることができます。

私はこれに要約します:

ライブラリ ヘッダーtest_lib.h:

#ifdef __cplusplus
extern "C"
#endif
void test_func() __attribute__ ((weak));    

ライブラリの実装test_lib.cpp:

#include "test_lib.h"
#include <iostream>
extern "C"
void test_func()
{
    std::cout << "in test_func\n";
}

C テストtest_main.c:

#include <stdio.h>
#include "test_lib.h"

int main(void)
{
    if (test_func){ printf("+\n"); }
    else{ printf("-\n"); }
    return 0;
}

C++ テストtest_main_cpp.cpp:

#include <iostream>
#include "test_lib.h"

int main(void)
{
    if (test_func){ std::cout << "+\n"; }
    else{ std::cout << "-\n"; }
    return 0;
}

便宜上、コンパイルして実行するスクリプト:

#!/bin/bash

g++ -shared -fPIC test_lib.cpp -o libtest.so

gcc test_main.c -o test_c
g++ test_main_cpp.cpp -o test_cpp

# output should be "-"
./test_c
./test_cpp

# output should be "+"
LD_PRELOAD=libtest.so ./test_c
LD_PRELOAD=libtest.so ./test_cpp

予想される出力は次のとおりです。

-
-
+
+

私が得るものは次のとおりです。

-
-
-
-

そして最後に少し追加情報:

$ uname -a
Linux bermuda-iii 3.8.6-1-ARCH #1 SMP PREEMPT Sat Apr 6 07:27:01 CEST 2013 x86_64 GNU/Linux
$ gcc --version
gcc (GCC) 4.8.0
$ nm libtest.so | grep -i func
0000000000000858 W test_func
$ nm test_c | grep -i func
             w test_func
$ nm test_cpp | grep -i func
             w test_func

したがって、(デ)マングリングは正常に機能しているようで、シンボルtest_funcは実行可能ファイルに認識されています。しかし、「LD_PRELOAD」は機能していないようです。

私は何が欠けていますか?

4

1 に答える 1