如何在不可修改的源代码中使用DLL函数?

时间:2018-05-18 11:52:49

标签: c++ dll overloading

我是一个菜鸟所以请,请不要犹豫,详细说明你的意思。 我目前正在研究c ++中的第三方源代码,我正在开发插件,并且我不想因为显而易见的原因而修改(新版本出来,可用性等)。第三方代码的autors通过使用外部指令文件准备使用插件,其中参数等用关键字指定。对象创建读取指令中的关键字,并在工厂中查找是否已声明关键字。如果是,则调用指定的构造函数,否则调用默认构造函数。 到目前为止,我只需要处理这些与工厂相关的对象,因此我创建了定义子类的dll,并使用指令文件调用关联的构造函数。然后,我可以在主程序的其余部分中使用dll中定义的重载或覆盖函数(因为构造的对象是子类)。

这个主题的原因是我不想触及初始源代码,并且仍然希望重载/覆盖主程序中使用的函数,但它没有在工厂相关对象中定义。这是TrajectoryLoader类中函数的主程序声明:

namespace NAF {
    class TrajectoryLoader : public Object {
    public:
        NAF_CORE_API TrajectoryLoader() { _good = false; }
        NAF_CORE_API virtual ~TrajectoryLoader() {}
        NAF_CORE_API virtual bool LoadTrajectory(std::string filename);
        NAF_OBJ_DECLARES(TrajectoryLoader)
    private:
        CSVRange _range;
        bool _good;
    };

}

我想要重载/覆盖的是NAF_CORE_API虚拟bool LoadTrajectory,它加载并解析和参数文件以创建稍后要使用的“轨迹”对象。我需要允许不同格式的文件,因为它现在只获得特定的写法语法。

我想我可以为TrajectoryLoader创建一个子类并调用LoadTrajectory的重载版本,但主代码调用LoadTrajectory如下:

traj = std::make_shared<TrajectoryLoader>();
traj->NAFSetName(id);
traj->LoadTrajectory(v);

使用“v”我要加载的文件的全名。即使定义了一个子类,我希望“traj”来自父类,Loadtrajectory也是非重写函数(我也测试过它)。

接下来的问题是:我可以为LoadTrajectory的重载版本调用第二段代码吗? (我假设答案是否定的)我如何使主程序(我不想修改)在执行期间从我自己的dll调用函数?

我希望我的请求清楚,但我承认我只是为这个项目启动了C ++,因此我可能错过了一些可行的简单技巧。我在互联网上看了两天试图寻找方法,但没有。

也有可能无法做到这一点,在这种情况下,我将不得不找到另一种让事情有效的方法。

感谢您的帮助,对于长篇文章感到抱歉,或者如果这是重复的话,我可能会缺少技术术语以找到我想要的内容。

有了爱,

天敏

编辑:试图澄清问题。

1 个答案:

答案 0 :(得分:0)

问题基本上来自EXE的这个片段:

traj = std :: make_shared(); traj-&GT; NAFSetName(ID); traj-&GT; LoadTrajectory(ⅴ);

由于编译器在构建EXE时看到了该片段,因此它知道LoadTrajectoryTrajectoryLoader::LoadTrajectory。编译器可以内联函数,而不是进行实际调用。这意味着它接受函数的主体并将其插入到您期望CALL汇编指令所在的位置。

如果没有这样做,编译器将直接调用TrajectoryLoader::LoadTrajectory

现在,在运行时,操作系统知道一些函数调用,其中编译器(或程序员)已指示调用是跨越DLL的。这就是插件机制在这里的工作原理。但是,操作系统看不到EXE或DLL内部的所有函数调用。