1

我对在类上使用 dllimport 感到困惑,希望能得到一些帮助!我已经构建了以下 C++ 代码并将其打包为动态库:

class __declspec(dllexport) normaldog {
    normaldog(){};
    ~normaldog(){};
    char* call() { return "woof!"; }
}

class __declspec(dllexport) stupiddog {
    stupiddog(){};
    ~stupiddog(){};
    char* call() { return "meow?"; }
}

现在,我想在我的主程序中使用其中一个类(实例化、调用方法和销毁),就像我对普通类所做的那样。我的问题是,我不知道在运行时之前我会使用哪个:我可以在第一个 exec 上调用一个normaldog ,在第二个 exec 上调用一个愚蠢的。我想在我的编译代码中为此使用别名,这将在运行时解析。

怎么做?我会说typedef是我最好的选择,但我找不到正确的语法来使用它......

在此先感谢您的帮助 !

4

1 回答 1

0

该问题与 DLL 无关(如果类是在实际程序中定义的,则情况相同)。

Typedef 不是你想要的。这是一个完全静态的功能,因此它不会帮助您在运行时解决任何问题。

你想要的是多态性。让两个类都继承自一个(可能是抽象的)基类:

class __declspec(dllexport) Dog
{
public:
    Dog() {}
    virtual ~Dog() {}

    virtual const char* Call() = 0;
};

class __declspec(dllexport) NormalDog : public Dog
{
public:
    NormalDog() {}
    ~virtual NormalDog() {}

    virtual const char* Call() { return "woof!"; }
};

class __declspec(dllexport) StupidDog : public Dog
{
public:
    StupidDog() {}
    virtual ~StupidDog() {}

    virtual const char* Call() { return "meow?"; }
};

然后,您可以在运行时决定要实例化哪个,然后通过 Dog 指针使用它:

Dog* pDog;

if (...)
    pDog = new NormalDog();
else
    pDog = new StupidDog();

pDog->Call();

编辑:如果你不能修改 DLL 的类,你可以使用这个解决方法:

class DogObject
{
public:
    DogObject() {}
    virtual ~DogObject {}
};

class NormalDogObject : public DogObject
{
private:
    NormalDog m_dog; // the DLL's NormalDog

public:
    NormalDogObject() {}
    virtual ~NormalDogObject() {}

    NormalDog& GetNormalDog() { return m_dog; }
    const NormalDog& GetNormalDog() const { return m_dog; }
};

class StupidDogObject : public DogObject
{
private:
    StupidDog m_dog; // the DLL's StupidDog

public:
    StupidDogObject() {}
    virtual ~StupidDogObject() {}

    StupidDog& GetStupidDog() { return m_dog; }
    const StupidDog& GetStupidDog() const { return m_dog; }
};

然后使用 dynamic_cast 找出 DogObject 的运行时类型并对其调用方法:

DogObject* pDog;

if (...)
    pDog = new NormalDogObject();
else
    pDog = new StupidDogObject();

if ((NormalDogObject* pNormalDog = dynamic_cast<NormalDogObject*>(pDog)) != nullptr)
    pNormalDog->Call();
else if ((StupidDogObject* pStupidDog = dynamic_cast<StupidDogObject*>(pDog)) != nullptr)
    pStupidDog->Call();

当然,如果所有类都具有相同的方法(如本例所示),您可以在 DogObject 中将这些方法声明为纯虚拟方法,并让派生类通过委托对 DLL 类的方法的调用来实现它们(基本上将所有内容包装在你自己的类层次结构)。这会引出一个问题,为什么 DLL 的开发人员一开始不这样做?

于 2013-02-28T19:58:13.787 回答