如何在C ++中正确创建/实现拦截器库?

问题描述 投票:0回答:2

这是我的第一篇文章!我已经实现了一个小的C ++程序,该程序使用foo实现作为共享库。共享库包含两个功能:get_number()print_text()

目标是拦截器库(共享库)更改foo库的功能,这样

  • [get_number()应该替换为始终返回333的函数。
  • print_text()应该换行,以便在执行原始功能之前和之后打印一些文本。

源代码如下:

foo.hpp

#ifndef _FOO_HPP
#define _FOO_HPP

namespace foo {

    int get_number();

    void print_text();

}

#endif

foo.cpp

#include "foo.hpp"

#include <iostream>

namespace foo {

    int get_number()
    {
        return 13;
    }

    void print_text()
    {
        std::cout << "Hello World!" << std::endl;
    }
}

interceptor.hpp

#ifndef _INTERCEPTOR_HPP
#define _INTERCEPTOR_HPP

#include <iostream>

namespace interceptor {

    int get_number();

    void print_text();

}

#endif

interceptor.cpp

#include "interceptor.hpp"

namespace interceptor {

    int get_number()
    {
        return 333;
    }

    void print_text()
    {
        // Print here some text.
        std::cout << "Hello World!" << std::endl;
        // Print here some test.
    }
}

main.cpp

#include <iostream>

#include "foo.hpp"

int main(void)
{
    std::cout << "Number: " << foo::get_number() << "\n" << std::endl;
    foo::print_text();

    return 0;
}

在有和没有拦截器库的情况下运行主可执行程序可能看起来像这样:

$ ./main
Number: 13

Hello World!

$ LD_PRELOAD=$PWD/interceptor.so ./main
Number: 333

Hi before
Hello World!
Bye after

我是共享库和拦截器库中的初学者。

我希望有人可以帮助我解决我的问题。

c++ linux g++ shared-libraries
2个回答
1
投票

main.ofoo.so链接在一起,例如:

g++ -o main main.o foo.so

如果您尝试运行

./main

您会得到一个错误,因为foo.so不在动态链接程序查找它的系统库路径中。我们也可以告诉它在当前文件夹中查找:

$ LD_LIBRARY_PATH=. ./main
Number: 13

Hello World!

现在带有interceptor.so

$ LD_LIBRARY_PATH=. LD_PRELOAD=$PWD/interceptor.so ./main
Number: 13

Hello World!

您可以看到没有任何变化。这是因为您的interceptor.so实际上没有包含foo::get_numberfoo::print_text的定义。它包含interceptor::get_numberinterceptor::print_text的定义,但是main永远不会调用它们!

[interceptor.cpp应该实现与foo.cpp相同的功能,因此在将namespace interceptor替换为namespace foo并重新编译之后:

$ LD_LIBRARY_PATH=. LD_PRELOAD=$PWD/interceptor.so ./main
Number: 333

Hello World!
© www.soinside.com 2019 - 2024. All rights reserved.