代码之家  ›  专栏  ›  技术社区  ›  Alexey Malistov

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

  •  1
  • Alexey Malistov  · 技术社区  · 16 年前

    我的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程序不会改变函数的结果。

    5 回复  |  直到 16 年前
        1
  •  1
  •   Steve Jessop    16 年前

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

    因为超载, char *First() const char *First() const 是不同的功能。你们两个可以在同一个班上。所以任何名称管理方案都必须将它们映射到不同的名称,这在绑定方面显然是一个问题。

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

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

        2
  •  3
  •   Kirill V. Lyadvinsky    16 年前

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

    指向cv限定类型的指针或引用不需要实际指向或引用cv限定对象,但将其视为指向或引用cv限定对象;即使引用的对象是非常量对象,并且可以通过其他访问路径进行修改,也不能使用常量限定访问路径来修改对象。[注:cv限定符受类型系统的支持,因此在没有强制转换(5.2.11)的情况下,它们不能被转换。]

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

        3
  •  0
  •   ufukgun    16 年前

    因为你改变了你的界面,你必须重新编译(我想)

        4
  •  0
  •   Glen    16 年前

    可能不行。尽管最容易确定的方法是试试看

        5
  •  0
  •   Steven Keith    16 年前

    我觉得这样不行。更改dll的接口通常需要重新编译链接到它的可执行文件。

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

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