我可以在不重新编译exe文件的情况下更改dll接口吗?

发布于 2024-08-12 06:00:25 字数 484 浏览 4 评论 0原文

我的 DLL 中有一个抽象类。

class Base {
  virtual char * First() = 0;
  virtual char * Second() = 0;
  virtual char * Third() = 0;
};

这个动态库和这个界面已经使用了很长时间了。 我的代码中有错误。现在我想更改此接口

class Base {
  virtual const char * First()  const = 0; 
  virtual const char * Second()       = 0;
  virtual       char * Third()  const = 0;
};

某些 EXE 程序使用我的 DLL。 EXE 程序无需重新编译即可运行吗? 独立考虑新界面每一行的变化。

注意:当然,EXE程序不会改变函数结果。

I have an abstract class in my DLL.

class Base {
  virtual char * First() = 0;
  virtual char * Second() = 0;
  virtual char * Third() = 0;
};

This dinamic library and this interface are used for a long time.
There is my mistake in my code. Now I want to change this interface

class Base {
  virtual const char * First()  const = 0; 
  virtual const char * Second()       = 0;
  virtual       char * Third()  const = 0;
};

Some EXE-program uses my DLL. Will the EXE-program work without recompilation?
Consider changes in each line of new interface independently.

Note: of course, EXE-program does not change functions results.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

云裳 2024-08-19 06:00:25

您的 EXE 可能会更改函数的结果,因为它是 char*。现在是const char*。根据 C++ 标准 7.1.5.1/3-4,更改 const 对象将导致未定义的行为:

对 cv 限定类型的指针或引用实际上不需要指向或引用 cv 限定对象,但它会被视为指向或引用; const 限定的访问路径不能用于修改对象,即使引用的对象是非常量对象并且可以通过其他访问路径进行修改。 [注意:cv 限定符受类型系统支持,因此如果不进行强制转换 (5.2.11),它们就无法被破坏。 ]

除了声明为可变的任何类成员 (7.1.1) 都可以修改之外,任何修改 const 的尝试
对象在其生命周期(3.8)会导致未定义的行为。

Your EXE could change result of function since it was char*. Now it is const char*. And changing const object will lead to undefined behavior according to C++ Standard 7.1.5.1/3-4:

A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path. [Note: cv-qualifiers are supported by the type system so that they cannot be subverted without casting (5.2.11). ]

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const
object during its lifetime (3.8) results in undefined behavior.

泪痕残 2024-08-19 06:00:25

它“不应该”起作用,但你永远不知道你的运气。

由于重载,char *First()const char *First() const 是不同的函数。你可以在同一个班级里同时拥有两者。因此,任何名称修改方案都必须将它们映射到不同的名称,这在绑定方面显然是一个问题。

但是,这些是虚拟调用,并且您将三个函数按相同的顺序替换为它们的等效函数。我不知道 MSVC 的 vtable 方案的任何细节,特别是偏移量是静态确定的还是动态绑定的。如果是前者,exe 可能可以绑定新的 vtable。函数指针可能恰好起作用,因为调用约定不依赖于 cv 限定(即,const char* 的返回方式与 char* 相同) code> is 和 const this 的传递方式与非 const this is 相同)。

即使它确实有效,我也不想依赖它,除非它是微软专门解决和保证的东西。

It "shouldn't" work, but you never know your luck.

Because of overloading, char *First() and const char *First() const are different functions. You could have both in the same class. So any name-mangling scheme has to map them to different names, which obviously is a problem when it comes to binding.

But, these are virtual calls, and you have three functions replaced by their equivalents in the same order. I don't know any details of MSVC's vtable scheme, in particular whether the offsets are statically determined or dynamically bound. If the former, it's possible that the exe can bind against the new vtable. The function pointers might just so happen to work, because the calling convention doesn't depend on cv-qualification (that is, a const char* is returned the same way a char* is, and const this is passed the same way non-const this is).

Even if it does work, I wouldn't want to rely on it unless it's something that MS specifically addresses and guarantees.

穿越时光隧道 2024-08-19 06:00:25

既然你改变了你的界面,你必须重新编译(我认为)

since you change your interface, you have to recompile (i think)

旧城烟雨 2024-08-19 06:00:25

可能行不通。虽然最简单的确定方法就是尝试看看

Probably won't work. Though the easiest way to know for sure is to try it and see

穿越时光隧道 2024-08-19 06:00:25

我认为这行不通。更改 DLL 的接口通常需要重新编译链接到它的可执行文件。

此外,您可能需要更改可执行文件中的代码,因为您更改了函数签名。

最后,如果您要更新/追加接口,最好对原始接口进行子类化。这将防止任何现有代码被破坏。

I don't think this will work. Changing the interface of a DLL usually requires the executable that links to it to be recompiled.

In addition, you will likely need to make changes to the code in the executable, as you have changed the function signatures.

Lastly, if you are going to update/append an interface, you would be best to subclass the original interface. This will prevent any existing code from breaking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文