【问题标题】:How to create/implement an interceptor library correctly in C++?如何在 C++ 中正确创建/实现拦截器库?
【发布时间】:2019-11-27 16:21:15
【问题描述】:

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

目标是拦截器库(共享库)改变 foo-library 的功能,使得

  • 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.
    }
}

ma​​in.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

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

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

【问题讨论】:

  • 请每个 stackoverflow.com 问题一个问题。每个问题都必须是一个特定的问题。 “我如何做 X”,其中 X 是一些主要任务,不是一个具体的问题。这不是 stackoverflow.com 的用途,这不是一个教程网站。
  • 对此我感到非常抱歉。我改变了我的帖子。
  • @RainerH。你让你的问题更广泛。我确实尝试回答问题 (1),但现在已经不存在了。

标签: c++ linux g++ shared-libraries


【解决方案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=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=interceptor.so ./main
Number: 333

Hello World!

【讨论】:

  • 非常感谢您的回复!我已经更改了拦截器实现中的命名空间并重新编译了源代码。现在我了解了如何编译和链接该程序(以前我尝试过不同的编译和链接指令)。我还有一个问题:如何将 foo::print_text() 函数包装在拦截器中,以便在执行原始函数之前和之后打印一些文本?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 2012-04-06
  • 2015-03-18
  • 2019-04-27
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
相关资源
最近更新 更多