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

标签 c++ dll

我有一个 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/

相关文章:

c++ - 在 C/C++ 中声明函数然后定义它是否内 union 法?

c++ - 构建两个相互依赖的dll

PHP 7 : Missing VCRUNTIME140. DLL

c++ - 在 C++ Windows 应用程序中引用 native C++ DLL 仅在添加为引用时有效

c# - 使用 ILMerge 合并 .dll 文件失败

c++ - 如何在 CentOS 7.3 64bit 上安装 boost 库?

c++ - Eclipse IDE C++ 不工作 C++

c++ - 在 Windows-8 64 位中通过 eclipse luna 运行 valgrind/其他内存检查

c++ - 为什么默认构造函数不适用于 `vector::emplace_back`

postgresql - Postgres ODBC 驱动脚本安装