V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
a1lenyang
V2EX  ›  C++

c++动态链接库的问题

  •  
  •   a1lenyang · 2020-04-15 12:03:06 +08:00 · 1728 次点击
    这是一个创建于 1675 天前的主题,其中的信息可能已经有所发展或是发生改变。
    //头文件 TaxCaculator.h
    class _declspec(dllexport) TaxCalculator {
    private:
        double income;
        double taxRate;
    public:
    		int a;
    		int b;
        TaxCalculator(double income, double taxRate);
        ~TaxCalculator();
        virtual double calculate();
    };
    extern "C" _declspec(dllexport) TaxCalculator* CreateObjet (double income, double taxRate);
    
    //实现文件 TaxCaculator.cpp
    #include "TaxCaculator.hpp"
    TaxCalculator::TaxCalculator(double income, double taxRate){
        this -> income = income;
        this -> taxRate = taxRate;
      	a = 2;
      	b = 5;
    }
    TaxCalculator::~TaxCalculator(){
        
    }
    double TaxCalculator::calculate(){
        return (income * taxRate);
    }
    
    • 以上程序生成 dll,然后在同一个编译器中建立一个新的客户文件调用
    #include "TaxCalculator.h"
    #include <iostream>
    int main() {
      TaxCaculator* caclulator = CreateObject(1000, 0.3);
        int a = calculator -> a;
        int b = calculator -> b;
      return 0;
    }
    
    
    • 在 dll 文件中,改变 a 和 b 定义的位置,然后重新编译,**客户文件重新调用新的 dll 文件,为什么两次的结果是颠倒的?**这里不是很理解。
    • 同理,在 dll 文件中定义两个虚函数
        virtual int fa();  
        virtual int fb();  
    

    分别实现之。 编译服务器端和客户端。得到版本 1.

    改变定义顺序:

    virtual int fb(); 
    virtual int fa();
    

    编译服务器端和客户端。得到版本 2. 打乱版本的搭配顺序,调用将出现错乱。这又是为什么?

    6 条回复    2020-04-15 12:45:31 +08:00
    codehz
        1
    codehz  
       2020-04-15 12:14:31 +08:00 via Android
    因为虚函数是按声明顺序保存在虚表里的,所以实际上你写 x.fa()的时候编译器就会生成对虚表第一个函数的调用,所以你改变声明顺序就会导致调用错误函数
    catcn
        2
    catcn  
       2020-04-15 12:17:46 +08:00
    不要导出 c++
    rigortek
        3
    rigortek  
       2020-04-15 12:27:33 +08:00 via iPhone
    加 log 调试一下看为什么错乱
    a1lenyang
        4
    a1lenyang  
    OP
       2020-04-15 12:37:39 +08:00
    @codehz 好的,虚函数明白了,原来是我忘记了头文件是没有改变的,只是改变了 dll 的版本。
    虚函数的顺序有虚表保存,请问变量 a, b 也是以某种顺序存储的吗?
    codehz
        5
    codehz  
       2020-04-15 12:43:32 +08:00 via Android
    @a1lenyang 变量顺序是不变的,但是要注意虚表会在开头额外占用一个指针,多重继承的时候则有可能会更多,因此最好每次变更都同时更新头文件并重新编译其他依赖的库
    a1lenyang
        6
    a1lenyang  
    OP
       2020-04-15 12:45:31 +08:00
    @codehz 明白了,谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3962 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 04:12 · PVG 12:12 · LAX 20:12 · JFK 23:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.