首页 > 解决方案 > 如何在不可修改的源代码中使用 DLL 函数?

问题描述

我是菜鸟,所以请不要犹豫,详细说明并解释您的意思。我目前正在使用 c++ 编写第三方源代码,我正在为此开发插件,并且出于明显的原因(新版本发布、可共享性等)我不想修改。第三方代码的作者通过使用外部指令文件为插件的使用做好了准备,其中参数等是用关键字指定的。对象创建读取指令中的关键字,并在工厂中查找关键字是否已声明。如果是,则调用指定的构造函数,否则调用默认构造函数。到目前为止,我只需要处理这些与工厂相关的对象,因此我创建了定义子类并使用指令文件调用相关构造函数的 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 虚拟布尔 LoadTrajectory,它加载和解析参数文件以创建稍后使用的“轨迹”对象。我需要允许不同格式的文件,因为它现在只能获得特定的写作语法。

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

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

“v”是我要加载的文件的全名。即使定义了子类,我希望“traj”来自父类,Loadtrajectory 将是非覆盖函数(我也对其进行了测试)。

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

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

也有可能这是不可能的,在这种情况下,我将不得不找到另一种方法来使事情正常进行。

谢谢你的帮助,很抱歉这篇文章很长,或者如果这是重复的,我可能缺少技术术语来找到我想要的东西。

有爱,

莫蒂默

编辑:试图澄清这个问题。

标签: c++dlloverloading

解决方案


问题基本上是EXE中的这个片段:

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

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

即使没有这样做,编译器也会插入一个对完全的直接调用TrajectoryLoader::LoadTrajectory

现在在运行时操作系统知道一些函数调用,其中编译器(或程序员)已经表明调用是跨 DLL 的。这就是插件机制在这里的工作方式。但是,EXE 或 DLL 内部的所有函数调用对操作系统都是不可见的。


推荐阅读