如何使链接器更喜欢从给定位置实现

How to make linker prefer implementation from a given location

本文关键字:定位 位置 实现 更喜欢 何使 链接      更新时间:2023-10-16

我需要一种方法使链接器更喜欢一种实现而不是另一种。我的用例如下:我正在编写单元测试,我需要模拟一些对象。问题是那些对象在"主"库中,即使在调试中我也不能扔掉,因为许多SDK的东西都在那里。

所以我已经实现了这些模拟,但现在看来,链接器更喜欢从"主"库实现,至少我的代码没有被调用。我使用ARM RVCT 4 c++编译器与Symbian工具链,如果这是重要的。

任何想法(甚至变通方法)都非常感谢!

编辑:我需要模拟静态方法调用,可能这很重要,因为我认为静态方法与普通方法相比以其他方式联系在一起。

通常mock不是在链接阶段完成的,而是在代码中解决的。依赖注入是首选技术之一。也就是说,您应该对代码进行建模,以便可以在真实实现和模拟实现之间进行选择。

例如,您想在代码中创建对象A。一种方法是使用A的两个不同实现,并在构建测试时链接到模拟实现。依赖注入方法建议有一个指向接口的指针,并从外部(例如,在构造函数中)传递对象本身。然后,从生产代码中您将通过实际对象,从单元测试中您将通过模拟。

如果你绝对需要在链接级别上这样做,并且你无法避免链接"真正的"对象,那么你可以包装这些对象吗?下面是一个例子:

假设这是您要测试的代码:

void my_method()
{
    ProblematicClass c;
    c.Call();
}

ProblematicClass在两个地方实现:一个在SDK中,另一个是您的模拟。如果可以将ProblematicClass封装在另一个类中,则可以创建两个源文件:

生产文件:

struct Wrapper
{
public:
    void Call() { m.Call(); }
private:
    ProblematicClass m;
}
模拟文件:

struct Wrapper
{
public:
    void Call() { m.Call(); }
private:
    MockClass m;
}

现在源代码在您的控制之下,您不必更改测试代码的设计,并且可以排除生产实现。您的测试代码当然必须更改为:

void my_method()
{
    Wrapper c;
    c.Call();
}

我不确定我完全理解你的问题是什么,但它可能值得检查$sub$$$super$$的文档:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0206j/Chdefdce.html。