在 EXE/DLL 之间传递数据

Pass data between EXE/DLL

本文关键字:数据 之间 DLL EXE      更新时间:2023-10-16

I have DLL and EXE app.DLL 在 EXE 中注册。然后在类A的 EXE 实例中创建为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。此外,存储在对象Resultvector 不包含任何指针,因此它应该是 vector 的深层副本。 一种解决方案是在 DLL 中分配Result对象,将其作为对调用方法的引用传递并填充所有必要的数据,但我想获得副本作为结果。 为什么会出现此问题?如何修复它?EXE 和 DLL 在 Visual Studio 的同一解决方案中,必须使用 \MT 或 \MTd 进行编译,并且无法更改它。

向量的内存在 DLL 中分配并在 exe 中释放,因为向量可能在其返回中使用移动语义(甚至只是 RVO(,它只是将指针移动到分配的内部。当您使用静态 CRT 时,这意味着内存被分配了一个 crt,并释放了另一个实例,这会导致坏事。

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

如果选择跨 DLL 接口公开 c++ 对象,则必须确保 EXE 和 DLL 都使用相同的编译器版本,并且与/MD 链接。如果您不能使用/MD,您将永远无法可靠地工作。

当然,您可以预先分配向量并在调用中填写它,但这只是掩盖问题,直到事情不可避免地发生变化。