加载外部类C ++

称重

我正在尝试加载.dll文件中定义的类。但是,有两种在dll中定义类的方式略有不同。我不确定哪种方法更合法,我也不知道为什么第二种方法也行得通。这是一个简单的示例:

方法1:main.cpp

#include <iostream>
#include <windows.h>
#include <memory>
#include "bar.h"

using namespace std;

typedef bar* (* MYDLLPROC)();

int main()
{
    unique_ptr<bar> theresult;
    auto thelib = LoadLibrary(TEXT("foo.dll"));

    if (thelib != NULL) {
        MYDLLPROC theprocs = (MYDLLPROC)GetProcAddress(thelib, "Myfoo");
        cout << "load successfully" << endl;
        theresult.reset(theprocs());
        theresult->printmsg();
    } else {
        cout << "cannot load the dll" << endl;
    }

    return 1;
}

在中bar被定义为纯虚拟类bar.h

class bar {
public:
    virtual ~bar() {};
    virtual void printmsg() = 0;
};

foo.dll源文件中:

#include <iostream>
#include <windows.h>
#include "bar.h"

using namespace std;

class foo: public bar {
public:
    foo() { cout << "foo is instantiated" << endl; }
    ~foo() {}
    void printmsg() final { cout << "msg from foo print" << endl; }
};

extern "C" __declspec(dllexport) foo* __cdecl Myfoo()
{
    return new foo();
}

在第一种方法中,纯虚拟类bar用作接口,并且它的成员函数被foodll加载时的成员函数覆盖是有意义的

但是,我发现foo不必继承自bar,只要foo有了Vtable ,一切仍然可以使用:

在第二种方法中,除以下内容的定义外,其他内容均相同foo

#include <iostream>
#include <windows.h>

using namespace std;

class foo {
public:
    foo() { cout << "foo is instantiated" << endl; }
    virtual ~foo() {}
    virtual void printmsg() final { cout << "msg from foo print" << endl; }
};

extern "C" __declspec(dllexport) foo* __cdecl Myfoo()
{
    return new foo();
}

谁能让我知道第二种方法为什么起作用?我有点困惑,因为foobar并没有关系,但是中的成员函数bar仍然可以被覆盖。

生锈的

因此,您将返回的函数转换为返回foo*的函数bar*,然后调用它。

最终结果是您有一个指向foo不相关类型的指针bar以任何方式使用它都会导致不确定的行为

printmsg在两个特定的虚拟表中,虚函数的位置是相同的,因此在这种特定情况下似乎可以使用,因此bar::printmsg在实例上foo调用仅会调用“虚拟表中的第N个条目”。如果将另一个虚拟成员添加到foobefore printmsg,则可能会调用它(否则该程序可能会崩溃)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章