dll接口中std :: vector的正确用法(带有虚拟析构函数的类!)

问题描述 投票:0回答:1

我将尝试举例说明我的问题。

我有以下课程:

__declspec(dllexport) class myclass
{
public:
    int a;
    int b;
    myclass() {};
    virtual ~myclass() {};
    // ~myclass() {};
};

myclassDLL内部使用,该类仅包含类Test的定义(实际上,该类只是方法foo1foo2]的接口>):

class Test
{
public:
    void                 foo1   (std::vector<myclass>& val);
    std::vector<myclass> foo2   ();
};

extern "C"
{
    __declspec(dllexport) bool foo1(std::vector<myclass>& val)
    {
        val.clear();
        myclass tmp;
        val.push_back(tmp);
        val.push_back(tmp);
        val.push_back(tmp); //just an example!
        return true;
    }

    __declspec(dllexport) std::vector<myclass> foo2()
    {
        std::vector<myclass> val;
        myclass tmp;
        val.push_back(tmp);
        val.push_back(tmp);
        val.push_back(tmp); //just an example!
        return val;
    }
}

主应用程序打开DLL并调用接口方法以获得由方法foo1

foo2填充的向量。
typedef void                 (*FNPTR1)(std::vector<myclass>& val);
typedef std::vector<myclass> (*FNPTR2)();


int main()
{
    if (0)
    {
        HINSTANCE hInst = LoadLibrary(L"C:\\software\\mydll.dll");
        if (!hInst) { std::cout << "\nCould Not Load the Library";  return EXIT_FAILURE; }
        FNPTR1 fn = (FNPTR1)GetProcAddress(hInst, "foo1");
        if (!fn) { std::cout << "\nCould not locate the function";  return EXIT_FAILURE; }

        std::vector<myclass> tmp;
        fn(tmp);
        FreeLibrary(hInst);
        tmp.clear(); //crash here!
    }

    if (1)
    {
        HINSTANCE hInst = LoadLibrary(L"C:\\software\\mydll.dll");
        if (!hInst) { std::cout << "\nCould Not Load the Library";  return EXIT_FAILURE; }
        FNPTR2 fn = (FNPTR2)GetProcAddress(hInst, "foo2");
        if (!fn) { std::cout << "\nCould not locate the function";  return EXIT_FAILURE; }

        std::vector<myclass> tmp;
        tmp = fn();
        FreeLibrary(hInst);
        tmp.clear(); //crash here!
    }

    return 1;
}
}

[不幸的是,在两种情况下(使用foo1

foo2),当我尝试清除(或执行任何其他操作时,都出现“访问冲突读取XXXX”错误),然后在tmp矢量上卸载dll。

仅当myclass

的析构函数是虚拟的时,才会发生此问题。

在我的应用程序中,myclass

是自动生成的,不允许我修改析构函数定义。但是,如果该级别存在某种解决方案,我可以自由修改dll接口方法(即foo1 / foo2)。

我还想知道是否有可能告诉系统将tmp

向量用于主程序的堆,而不是.dll使用的堆。

我目前正在使用Visual Studio c ++ 2017,可以使用C ++ 11标准(或更高版本)

谢谢您的帮助。


回答以下评论:

  • 是的,exe和dll都使用相同的工具链进行编译。我正在使用/ MD选项。请告诉我是否应该检查其他内容。
  • 关于关于myclass

  • 派生的评论,我还尝试了从其派生的基类myclassbasemyclass的所有四种可能组合:

    1-具有标准析构函数的myclassbase和具有标准析构函数的myclass->确定

    2-具有标准析构函数的myclassbase和具有虚拟析构函数的myclass->崩溃

    3-具有虚拟析构函数的myclassbase和具有标准析构函数的myclass->崩溃

    4-具有虚拟析构函数的myclassbase和具有虚拟析构函数的myclass->崩溃

    因此,我可以得出结论,仅存在一个虚拟析构函数就足以产生问题。

我将尝试通过一个例子来解释我的问题。我有以下类:__declspec(dllexport)类myclass {public:int a; int b;我的课() {};虚拟〜myclass(){}; //〜...

c++ dll virtual-destructor
1个回答
0
投票

最后,我在计算机前,有时间仔细检查您的代码。

© www.soinside.com 2019 - 2024. All rights reserved.