gpt4 book ai didi

c++ - 在 C++ 中检测并清除从 dll 导入的错误对象

转载 作者:行者123 更新时间:2023-11-28 02:05:01 25 4
gpt4 key购买 nike

我有一个 dll(“so.dll”)定义如下,其中我有一个函数 TestWrongClass,它返回一个指针到类对象 (TestWrongClass)。

/////// "IOReader.h" //////////////
class IOReader
{
public :
IOReader() {};
virtual ~IOReader() {};
virtual bool open(const std::string &format,
const std::string &fileName, const int mask) = 0;
std::string errorMessage;
};
// "IOReader.h" Ends Here

// ---- so.dll ---- /
//////////////// sio.h ////////////
#ifdef SEIO_EXPORTS
#define SEIO_API __declspec(dllexport)
#else
#define SEIO_API __declspec(dllimport)
#endif

#include <string>
#include "IOReader.h"

class SReaderIO : public IOReader
{
public:
SReaderIO() {};
bool open(const std::string &format,
const std::string &fileName, const int mask)
{
return true;
}
};

class TestWrongClass
{
public:
TestWrongClass() { };
bool open(const std::string &format,
const std::string &fileName, const int mask)
{
return true;
}
};

SEIO_API TestWrongClass* CreateIOReader()
{
TestWrongClass * module = new TestWrongClass();
return module;
}

//// sio.h ends here ///////

//in the main executable I am loading the dll on run time
// and after creating a object of type TestWrongClass,
//I explicitly try to cast it with the wrong object, as follows

/// Main Source //
#include <iostream>
#include <windows.h>
#include "IOReader.h"

int main ()
{

HMODULE hDLL=LoadLibrary(L"sIO.dll");
CreateSealafineReaderFn _funcSelafinCreator = NULL;
_funcSelafinCreator = (CreateSealafineReaderFn) GetProcAddress (hDLL,
"CreateIOReader");

// Method 1
void *Iref = (_funcSelafinCreator)();
IOReader * locReader = NULL;
locReader = reinterpret_cast <IOReader *>(Iref); // but how to check
// that object locReader is not of base type IOReader
// so that I may call delete Iref
// If I try to do as follow, then I get illegal error from compiler
// locReader = dynamic_cast <IOReader *>(Iref); // illegal

// Method 2
try
{
locReader = dynamic_cast <IOReader *>((_funcSelafinCreator)());
// works but how can I check wrong casting and catch exception
} catch (std::bast_cast)
{
// how to clear the object created by CreateIOReader
}
}

//

我做这个过程的原因是检查是否有任何 dll,主程序将从 dll 目录中扫描可能有一个同名的方法,但是该方法创建的对象的返回指针类型可能不同,这是不希望的。(在上面提到的情况下,方法是 CreateIOReader)

如果我使用 dynamic_cast,我可以检查 bad_cast 异常,但是该对象已经在 dll 中创建,并且不会被释放,因为我无权访问 dll 的内部代码。

我使用 reintepret_cast 给出的上述方法有效,但是我无法检查是否返回了正确的对象类型。如果通过某种方法知道如果转换类型不正确,那么我可以在 Iref 指针上调用 delete“delete Iref”以从堆中清除对象。

有没有什么方法可以检查CreateIOReader方法是否创建了错误的对象,从而将其从可执行源代码中删除

最佳答案

对于这个问题dynamic_cast帮不了你。问题是您不知道函数的真正返回类型,而只是假装它是 IOReader*。 ,当它实际上可能是别的东西时(即 TestWrongClass* )。根据别名规则,这是不允许的。

对比一下情况:

class IBase { ... };
class IOReader : public IBase { ... };
class TestWrongClass : public IBase { ... };

你还知道你的函数返回一个 IBase* .在这里,动态类型转换确实可以帮助您,如 IOReaderTestWrongClass有共同的祖先,并且通过 IBase* 来引用两者都是有效的.

我不得不说这是一个奇怪的问题:调用库函数时您不知道会返回什么。我建议稍微改变一下设计。您可以(除其他事项外):

  1. 按照上述创建统一的层次结构
  2. 让调用返回类似 std::pair<int, void*> 的内容, 其中int (或 enum )将是确定返回内容的可靠方法,之后您可以 reinterpret_cast void*

如果您选择方法 1,那么要解决您的删除问题,您可以添加类似 destroy() 的函数到 IBase接口(interface),这会导致库删除对象(注意:delete 自己删除外部库提供给您的对象是个坏主意)。

如果您选择方法 2,那么也许您可以拥有类似 void destroy(int, void*) 的库函数,您可以将 std::pair 的成员传递给它如果您收到的不是您想要的东西。然后库可以使用这些来转换 void*回到正确的地方在内部删除它。

关于c++ - 在 C++ 中检测并清除从 dll 导入的错误对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37859129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com