在EXE / DLL之间传递数据

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

我有DLL和EXE应用程序。 DLL在EXE中注册。然后在EXE实例中,类A被创建为shared_ptr。接下来,将此实例传递给DLL,并在DLL端调用此实例的方法example

class Result
{
//Some attributes e.g std::vector
}

class A
{
public:
    A(){}
    ~A(){}

    Result example(){
        Result r;
        //Fill data in r object....
        return r;
    }
}

问题是当在DLL中的某处调用example时:

void someDLLMethod()
{
    //a is a shared pointer of A class
    {
        Result r = a->example();
    }//PROBLEM IS HERE DURING DEALLOCATING Result OBJECT

    //some stuff...
}

似乎在删除r对象期间出现问题。我知道什么时候我会尝试在EXE中分配一些内存然后尝试在DLL中释放这个内存然后可能发生内存问题,但在这种情况下,Result对象从EXE复制到DLL。此外,存储在Result对象中的向量不包含任何指针,因此它应该是向量的深层副本。一种解决方案是在DLL中分配Result对象,将其作为对被调用方法的引用传递并填充所有必要的数据,但我希望得到副本作为结果。为什么会出现此问题?如何修复它? EXE和DLL在Visual Studio的相同解决方案中,必须使用\ MT或\ MTd编译,并且不可能更改它。

c++ dll
1个回答
0
投票

向量的内存正在DLL中分配并在exe中释放,因为向量可能在其返回(或甚至只是RVO)中使用移动语义,它只是将指针移动到已分配的内部。当你使用静态CRT时,这意味着内存被分配了一个crt并且使用不同的实例自由,这导致了不良。

短篇小说 - 不要这样做。跨DLL边界公开C ++对象是不好的。您应该使用C接口或为此设计的接口 - 例如WinRT的。

如果确实选择在DLL接口上公开c ++对象,则必须确保EXE和DLL都使用相同版本的编译器并与/ MD链接。如果你不能使用/ MD,你永远不会让它可靠地工作。

当然你可以预先分配矢量并将其填入调用中,但这只是掩盖了问题,直到事情不可避免地改变了。

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