如何通过智能链接制作基于模块的程序

How to Make a Module Based Program With Intelligent Linking

本文关键字:模块 程序 于模块 智能 何通过 链接      更新时间:2023-10-16

首先,为了消除一些混淆,通过"具有智能链接的基于模块的程序",我的意思是让适配器类通过"即插即用"类型系统智能地继承单个头文件。该系统需要由一个简单的文件夹组成,例如"模块",用户只需将该模块的头文件和源文件拖放到文件夹中即可激活模块。我相信我需要利用一些脚本语言在适配器文件中生成所需的文本,例如#include。我也不太了解动态链接库,但如果可能的话,我更愿意使用它们(当然,它们需要产生相同的效果)。

举个例子,假设我的主要内容在这里:

moduleAdapter->Initialize();
while (true)
{
    moduleAdapter->Update();
    moduleAdapter->Render();
}
moduleAdapter->Release();

此循环应该能够将更新和呈现函数调用传递给所有链接的模块。

接下来,一个名为"module0.h"的示例模块文件,我可以有这样的东西:

class Module0
{
public:
    void Initialize();
    void Update();
    void Render();
    void Release();
}

我的目标是Windows,但多平台会很棒。也就是说,任何至少可以在Windows,OSX和Unix上运行的脚本语言都是完美的。

我需要但不明白该怎么做的是这个;我可以为管理模块并处理其输入和输出的"适配器"制作/执行什么操作,以及我可以制作和使用哪种脚本来执行此操作。我假设我需要脚本来手动编辑要写入#include等的文件。

提前谢谢你。

您可以使用接口(纯虚拟公共父类),pimpl习惯用法来隐藏实现,并使用动态加载的工厂函数从dll中实例化模块。

不需要任何标头,因为您的主程序通过多态性使用模块已知接口。

唯一非跨平台的事情是加载 DLL 并调用动态加载的工厂函数。


检查跨平台C++动态库插件加载器以获取跨平台解决方案。

这是我所拥有的。以下解决方案假定:

  1. 您始终有 1 个模块
  2. 您的模块具有由父类表示的单个接口
  3. 您已经编写了代码,只需要包含和链接正确的文件

该解决方案基于make实用程序,可以在MinGW或Cygwin环境中找到。它还假定您的make可以运行您的编译器,并且您的编译器g++ 。最后一个要求可能会被取消,因为 MS 编译器也可以从make使用,但我不知道如何。

以下文件构成了最小项目:

  • main.cpp 包含您的公共代码(示例中的 while 循环)
  • p1p2 是项目(模块)目录(称为 DIR
  • DIR/derived.h 是您要#include的相应模块标头
  • DIR/派生.cpp是您要链接的相应模块文件
  • base.h 声明模块的父类 - 接口
  • 生成文件make的源文件

主.cpp

#include "base.h"
#include "derived.h"
int main(void) {
    Base * module = new Derived();
    module->work();
}

P1/派生.h

#pragma once
#include <iostream>
#include "../base.h"
class Derived : public Base {
public:
    void work();
};

P2/Derived.H 与 P1/Derived.h 相同

P1/派生.cpp

#include "derived.h"
void Derived::work() {
    std::cout << "I am P1 module" << std::endl;
}

P2/派生.cpp

#include "derived.h"
void Derived::work() {
    std::cout << "I am P2 module" << std::endl;
}

碱基.h

#pragma once
#include <iostream>
class Base {
public:
    virtual void work() = 0;
};

生成文件

PROJECT ?=
SRCS    = main.cpp $(PROJECT)/derived.cpp
OUTPUT  = proj.exe
$(OUTPUT): $(SRCS)
    $(CXX) -I$(PROJECT) -o $@ $^

您使用make PROJECT=<PROJECT>运行编译。例如,make PROJECT=p1会导致运行以下命令

g++ -Ip1 -o proj.exe main.cpp p1/derived.cpp

它将带有p1/derived.cpp main.cpp正确编译为可执行文件proj.exe。运行它会导致打印"我是 P1 模块",这是预期行为。