C++ c++;DLL:包含项目中的类

C++ c++;DLL:包含项目中的类,c++,dll,include,C++,Dll,Include,案例:我正在制作一个应用程序,它应该能够获取某个文件夹中的所有DLL并加载它们。这些DLL充当模块,应该能够执行主应用程序中可能发生或不发生的某些任务 为了允许从我的DLL访问主应用程序,我已将主应用程序的文件夹添加到DLL的其他包含目录中。这样我就可以在主应用程序的头文件上调用#include,并使用它的类和函数 问题:主应用程序头文件中的include似乎会在试图从这些include访问函数的DLL中导致问题。例如:我的主应用程序中有一个类“Target”。该类有1个功能,包括: #ifnd

案例:我正在制作一个应用程序,它应该能够获取某个文件夹中的所有DLL并加载它们。这些DLL充当模块,应该能够执行主应用程序中可能发生或不发生的某些任务

为了允许从我的DLL访问主应用程序,我已将主应用程序的文件夹添加到DLL的其他包含目录中。这样我就可以在主应用程序的头文件上调用
#include
,并使用它的类和函数

问题:主应用程序头文件中的include似乎会在试图从这些include访问函数的DLL中导致问题。例如:我的主应用程序中有一个类“Target”。该类有1个功能,包括:

#ifndef D3DX9_INCLUDED
#define D3DX9_INCLUDED
#include <d3dx9.h> // Direct3D 9
#endif
如果我从目标类中删除了原始的include,那么就不会再有错误了。我可以毫无问题地将d3dx9包含在DLL中,但只有在目标类中未包含d3dx9时。将d3dx9.h直接包含到我的DLL中会产生与上面完全相同的错误。显然,这没有帮助,因为我需要在目标类和DLL中包含某些类和函数

我是否在为模块寻找不同类型的文件而不是DLL?在使用DLL时,我是否应该记住关于包含的内容

如果我忘记添加任何信息,请让我知道,我会尽我所能。 任何帮助都将不胜感激

更新:仅使用math.h和d3dx9.h includes将DLL剥离到最低限度,仍然会给我相同的错误

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <math.h>
#include <d3dx9.h> // Direct3D 9


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
//dllmain.cpp:定义DLL应用程序的入口点。
#包括“stdafx.h”
#包括
#包括//Direct3D 9
BOOL APICENT DllMain(模块HMODULE,
德沃德·乌尔打电话的理由,
LPVOID lpReserved
)
{
开关(ul\u呼叫原因\u)
{
案例DLL\u进程\u附加:
案例DLL\u线程\u连接:
案例DLL\u线程\u分离:
案例DLL\u进程\u分离:
打破
}
返回TRUE;
}

我无法解释头文件出现错误的原因,尽管从一个没有预编译头文件的最小示例开始,只包含
应该可以帮助您解决这些问题

对于如何允许插件DLL重用主应用程序的功能这一更大的问题,基本上有三种方法,它们在复杂性和耦合性上有所不同。您可能不想要求将来的所有插件都使用完全相同的编译器构建,是吗(或者在所有插件都准备好同时移动之前,无法将主应用程序移动到新的编译器)

  • 将整个应用程序放入一个DLL,主EXE只加载并调用这个应用程序逻辑DLL。然后插件DLL也可以使用应用程序逻辑DLL
  • 从主应用程序导出函数,并为EXE创建导入库<代码>\uu declspec(dllexport)也在EXE内部工作。需要对构建选项进行一些调整,以告知链接器创建导入库
  • 不要让插件DLL直接调用主应用程序,相反,当应用程序加载插件时,它会将上下文对象指针传递给plugin init函数。该上下文包含指向插件可能需要的函数的指针。上下文也可以在以后使用插件函数时提供,而不是在加载/初始化期间提供
  • 所有这些情况都得益于COM程序员熟悉的解耦技术。基本上,API应该只包含三种类型:

  • 原语
  • 普通的旧数据结构。所有数据成员都是非静态和公共的,没有非平凡的特殊成员函数
  • 指向接口的指针。接口是基类,只有纯虚拟函数,没有数据
  • 关键在于,它们在不同的编译器版本、不同的供应商甚至不同的语言中具有一致的内存布局。有时您需要
    #pragma pack
    来获得最终级别的布局控制

    我们从COM学到的另一件事是建立工厂,让对象通过
    Release()
    虚拟成员函数释放自己的内存。为了支持类似共享ptr的引用计数,COM使用
    AddRef()
    Release()
    对。这里重要的是,当销毁对象的代码是对象的一部分时,它会自动使用与工厂相同模块中的内存分配器


    COM不需要做的一件事是工厂接口。大多数情况下,简单的工厂函数已经足够好了。

    尝试从加载的DLL调用EXE中的函数会有一些有趣的复杂情况,但问题要简单得多。您是否尝试过在包含另一个标题之前包含#include?是的,我担心这会带来麻烦。我试着四处看看,但是大多数人都做了完全相反的事情,这更有意义,呵呵。我试着包括数学,但不幸的是没有运气。我还发现,由于某种原因,直接将d3dx9.h包含到DLL中会产生完全相同的错误。我猜这以前没有发生过,因为项目和dll的构建不正确。我已将此信息添加到主帖子中。在任何directx内容之前是否包含windows.h?我将尽快尝试。我想知道的是:即使应用程序有一个特定的include,也必须对DLL单独进行include?加载DLL如何在主应用程序的includes上而不是在DLL上触发错误?我将尝试在DLL中包含windows.h,并在可以的时候通知您!
    // dllmain.cpp : Defines the entry point for the DLL application.
    #include "stdafx.h"
    #include <math.h>
    #include <d3dx9.h> // Direct3D 9
    
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        }
        return TRUE;
    }