Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果DLL';s在C++;don';不支持二进制封装,什么时候使用它们是正确的?_C#_C++_Dll_Com - Fatal编程技术网

C# 如果DLL';s在C++;don';不支持二进制封装,什么时候使用它们是正确的?

C# 如果DLL';s在C++;don';不支持二进制封装,什么时候使用它们是正确的?,c#,c++,dll,com,C#,C++,Dll,Com,因此,我正在阅读COM和DLL,似乎如果我要更新DLL的实现(如果所需内存超过旧的需要),我需要使用DLL和更新的DLL重新编译程序。所以我只是想知道,什么时候使用DLL来支持COM是正确的?要重新编译所有的程序似乎几乎是不可能的,因为它们已经更新了一个依赖项 还有一个简单的附带问题:为什么二进制封装在.NET中不是问题?为什么我不必重新编译我的旧项目,也不必使用pimpl/不透明指针等等,就可以更改.NET中的DLL?二进制兼容性要求调用者和被调用者在公共ABI(应用程序二进制接口)上达成一致

因此,我正在阅读COM和DLL,似乎如果我要更新DLL的实现(如果所需内存超过旧的需要),我需要使用DLL和更新的DLL重新编译程序。所以我只是想知道,什么时候使用DLL来支持COM是正确的?要重新编译所有的程序似乎几乎是不可能的,因为它们已经更新了一个依赖项


还有一个简单的附带问题:为什么二进制封装在.NET中不是问题?为什么我不必重新编译我的旧项目,也不必使用pimpl/不透明指针等等,就可以更改.NET中的DLL?二进制兼容性要求调用者和被调用者在公共ABI(应用程序二进制接口)上达成一致

在Windows和Linux上,操作系统都指定了C调用的标准ABI,允许从任何其他语言调用C库。这也使得C++在DLL开发中很有用,只要C++在DLL内部使用,外表面使用“代码>外部”C“< /C>”和C兼容类型,如指针和原语,C兼容类型的普通旧数据复合。 <>在Linux和Windows上,C++ ABI与C++运行库相关。在Linux上,人们习惯于愚弄自己,认为C++共享对象也有OS提供的ABI,因为只有一个广泛使用的C++库——G+++的代码> LBSTDC++< /COD>,并且因为该库竭尽全力来保存相同的ABI。因此,前C++11
libstdc++
ABI实际上是一种标准,没有人因为混合ABI而遇到麻烦。现在,C++11迫使
libstdc++
打破了二进制兼容性,而clang的
libc++
越来越流行,因此Linux开发人员面临着Windows开发人员长期以来熟悉的问题

Windows上,没有任何C++标准库以同样的方式成为主导,部分原因是OS版本的厂商工具(微软Visual C++)的每一个版本都引入了不兼容性。是的,有些东西基本上保持不变(名称混乱),但另一些则发生了根本性的变化(分配器得到了低碎片堆支持,容器得到了调试迭代器,等等)

讽刺的是,Windows上的ABI标准比LINUX1好,因为Windows ABI指定一个C++特性-VTABLE布局来支持COM.< /P> <> DLL本地的C++的底线是,您可以在它内部自由使用它,但是对于解耦,DLL的公共表面只需要使用OS ABI中指定的特性——“代码>外部”C“< /Cord>”名称、C兼容类型和仅由虚函数组成的抽象基类。(没有静态成员,没有非静态数据,所有非静态函数都是虚拟的,构造函数受到保护)

<> p>但是如果你可以有耦合,你会得到更多的特征。如果应用程序中的每个组件都同意.NET ABI,那么它的所有特性都变得可用。NET的ABI是在向后和向前兼容的基础上开发的,从C++中的不兼容性和以前的尝试中吸取经验教训,比如java。 <>因为.NET ABI是如此稳定,耦合到它是一个可行的决定,就像许多Linux开发者连接到了前C ++ 11代码> STDLBC++ ABI。但是如果你打破兼容性,你就有可能失去所有可重用的库,这就是为什么连接到任何特定的Windows C++库被认为是坏主意的原因。编译需要每个库都有新版本。 当有一个单一的组件被粘贴在旧版本上,防止采用新的编译器时,你就失去了其他已经切换的组件的新开发。这就是为什么在Windows上C++的ABI耦合被广泛认为是一个很坏的想法。为什么图书馆的作者很少用二进制的形式分配Linux代码——他们把它分配到每个分发。n选择一个ABI,一致地使用它进行编译,并提供与之兼容的二进制软件包

当然,这只解决源代码之外的更改(对库类型的布局更改、参数传递顺序等)。如果源代码发生更改,例如添加新函数参数或更改类类型中的数据成员,那么无论您的兼容性有多好,都会出现不兼容(指定良好/稳定)ABI is..NET通过两阶段编译系统避免了其中的一些影响--当依赖项发生变化时,整个世界都会重新编译,因为JIT编译是在运行时完成的。但即使在.NET中,一些变化,如添加新的函数重载,在生效之前也需要重新编译源代码



实际上,我不确定,VTPLE布局也可能在Linux操作系统级别上指定。重要的是Linux C++二进制兼容性不再通用,这对许多依赖于ABI提供的事实上标准编译器的开发人员来说是一个巨大的惊喜,同时假设OS ABI保证了通用COMP。永久不兼容。因此,已经学会管理二进制兼容性不足的Windows开发人员处于更好的位置。

二进制兼容性要求调用者和被调用者就通用ABI(应用程序二进制接口)达成一致

Windows和Linux下,C++调用的标准ABI由OS指定,允许从任何其他语言调用C库。这也使得C++对于DLL开发很有用,只要C++在DLL内部使用,而外表面使用“代码>外”C。和C兼容类型,如指针和原语,以及C兼容类型的普通旧数据组合

<>在Linux和Windows上,C++ ABI与C++运行库相关,在Linux上,人们习惯于愚弄自己,认为C++共享对象也是