C:从dll动态加载类

对于我目前的项目,我想能够从一个dll加载一些类(这并不总是相同的,甚至当我的应用程序被编译时可能不存在)。对于给定的类也可能有几种替代方法(例如Direct3D9的实现,OpenGL的一个实现),但是在任何一个时刻只能加载/使用一个dll。

我有一组基类,它们定义了接口加上一些我想要加载的类的基本方法/成员(即反向计数),这些dll项目从那里创建时就派生类。

//in namespace base
class Sprite : public RefCounted//void AddRef(), void Release() and unsigned refCnt
{
public:
    virtual base::Texture *GetTexture()=0;
    virtual unsigned GetWidth()=0;
    virtual unsigned GetHeight()=0;
    virtual float GetCentreX()=0;
    virtual float GetCentreY()=0;
    virtual void SetCentre(float x, float y)=0;

    virtual void Draw(float x, float y)=0;
    virtual void Draw(float x, float y, float angle)=0;
    virtual void Draw(float x, float y, float scaleX, flota scaleY)=0;
    virtual void Draw(float x, float y, float scaleX, flota scaleY, float angle)=0;
};

事情是我不知道如何做到这一切,以便可执行文件和其他dll可以加载和使用这些类,因为只有使用dll只有一个dll,我可以让Visual Studio链接器排序全部使用.lib文件,我编译dll时得到。

我不介意使用工厂方法来实例化类,其中许多已经通过设计(即,一个Sprite类是由主Graphics类创建的,例如Graphics-> CreateSpriteFromTexture(base :: Texture *))

编辑:
当我需要编写一些用于python的c DLL时,我使用了一个名为pyCxx的库。结果dll基本上只导出一个方法,它创建了一个“Module”类的实例,然后可以包含工厂方法来创建其他类。

结果dll可以使用“import [dllname]”导入到python中。

//dll compiled as cpputill.pyd
extern "C" void initcpputill()//only exported method
{
    static CppUtill* cpputill = new CppUtill;
}

class CppUtill : public Py::ExtensionModule<CppUtill>
{
public:
    CppUtill()
    : Py::ExtensionModule<CppUtill>("cpputill")
    {
        ExampleClass::init_type();

        add_varargs_method("ExampleClass",&CppUtill::ExampleClassFactory, "ExampleClass(), create instance of ExampleClass");
        add_varargs_method("HelloWorld",  &CppUtill::HelloWorld,  "HelloWorld(), print Hello World to console");

        initialize("C Plus Plus module");
    }
...
class ExampleClass
...
    static void init_type()
    {
        behaviors().name("ExampleClass");
        behaviors().doc ("example class");
        behaviors().supportGetattr();
        add_varargs_method("Random", &ExampleClass::Random, "Random(), get float in range 0<=x<1");
    }

这是如何工作的,我可以用纯粹的环境来解决我的问题吗?

最简单的方法是,IMHO是一个简单的C函数,它返回一个指向其他地方描述的接口的指针。那么你的应用程序可以调用该界面的所有功能,而不需要知道它正在使用什么类。

编辑:这是一个简单的例子。

在您的主要应用程序代码中,您将为界面创建一个标题:

class IModule
{
public:
    virtual ~IModule(); // <= important!
    virtual void doStuff() = 0;
};

主应用程序编码为使用上面的界面,没有关于实际实现接口的任何细节。

class ActualModule: public IModule
{
/* implementation */
};

现在,模块 – 该DLL具有该接口的实际实现,甚至不需要导出这些类 – 不需要__declspec(dllexport)。模块的唯一要求是导出单个函数,这将创建并返回接口的实现:

__declspec (dllexport) IModule* CreateModule()
{
    // call the constructor of the actual implementation
    IModule * module = new ActualModule();
    // return the created function
    return module;
}

注意:错误检查留下 – 你通常会检查,如果新的返回正确的指针,你应该保护自己免受在ActualModule类的构造函数中抛出的异常。

然后,在你的主应用程序中,你需要的只是简单的加载模块(LoadLibrary函数),并找到函数CreateModule(GetProcAddr函数)。然后,您通过界面使用该类。

编辑2:您的RefCount(接口的基类),可以在主应用程序中实现(并导出)。那么所有的模块都需要链接到主应用程序的lib文件(是的,EXE文件可以像DLL文件一样具有LIB文件!)这应该是足够的。

http://stackoverflow.com/questions/431533/c-dynamically-loading-classes-from-dlls

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:C:从dll动态加载类