跨dll的c++类冲突
c++ class collision across dll
我有一个抽象基类(interface
),它在许多DLL中共享以从中继承。每个DLL都有一个导出的工厂符号,该符号动态创建一个对象并返回其指针。如果两个不同的DLL具有从同一抽象类继承的同名类,会发生什么?
class foo
{
public:
virtual void func()const=0;
};
Dll1
class bar: public foo
{
public:
virtual void func()const{
std::cout << "From Dll1" << std::endl;
}
};
Dll2
class bar: public foo
{
public:
virtual void func()const{
std::cout << "From Dll2" << std::endl;
}
};
主
int main()
{
foo* obj1;
foo* obj2;
// load DLLs
// import factory
// call factory to initialize objects
obj1->func(); // output: "From Dll1"
obj2->func(); // output: "From Dll2"
return typeid(*obj1) == typeid(*obj2);
}
返回true
,意味着obj1
和obj2
都是从同一个类实例化的。以及typeid(*obj1).name()
和typeid(*obj2).name()
返回相同的名称class bar
。如果不允许我自己控制DLL,有什么方法可以使用RTTI
来区分这些对象吗?类是否必须有一个机制来为这种情况提供其UUID
?
p.S.正如IInspectable所说,您可以将对象映射到其工厂。但若接口允许计算对象呢?DLL永远不会区分从不同模块返回的对象,因为它不知道工厂。这就是我想要使用RTTI
的主要原因。
首先,这种构造只有在运行时动态链接DLL时才可能实现。如果要使用加载时动态链接,则链接将标识导入库中的重复符号。因此,我们不再使用标准C++,而是使用特定于实现的行为:
HINSTANCE dll1Handle = LoadLibraryA("Test0410-1DLL1.dll");
HINSTANCE dll2Handle = LoadLibraryA("Test0410-1DLL2.dll");
fct f1, f2;
foo *obj1, *obj2;
if (dll1Handle == NULL || dll2Handle == NULL) {
cout << "Both DLL couldn't be uploaded!" << endl;
}
else {
f1 = (fct)GetProcAddress(dll1Handle, "myfactory");
f2 = (fct)GetProcAddress(dll2Handle, "myfactory");
if (f1 == NULL || f2 == NULL) {
cout << "Both factories couldn't be uploaded!" << endl;
}
else {
obj1 = f1();
obj2 = f2();
obj1->func();
obj2->func();
if (typeid(obj1) == typeid(obj2))
cout << "Same type"<<endl;
else cout << "Different type" << endl;
}
}
MSVC生成的代码发现两者具有相同的类型。但没有什么能保证这种行为。
使用虚拟函数的指针也很困难,因为你不能取obj->func
的地址,你需要取foo::func
的地址,这是一个相对地址,对于两个类都是相同的。
由于您的构造已达到ODR的极限,并且建立在特定于实现的行为之上,我认为安全区分类的最简单方法是在foo
中提供一个自制的虚拟类型标识函数,例如,该函数将组合类和dll名称。
相关文章:
- 写入位置0x0000000C时发生访问冲突
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- C++尝试深度复制唯一指针时出现内存访问冲突
- 错误:使用通用引用的声明冲突
- 如何解决GTest和LibTorch联动冲突
- 两个运营商的一些奇怪的冲突<<
- 如何在多个线程中创建 QSql数据库连接时防止名称冲突
- C++ 中动态二维数组的访问冲突
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- C++17 十六进制浮点文字单精度后缀冲突?
- 结构字段名称与 GDB 中的 STL 数组冲突
- 写入访问冲突异常
- C++ |匿名命名空间与命名空间 std 冲突
- 这个SSDO演示的GLSL版本要求是自我冲突的吗