标签: vtable

使用虚拟析构函数使非虚函数进行v表查找吗?

正是这个话题所要求的.还想知道为什么非CRTP的常见例子没有提到virtualdtor.

编辑:伙计们,请发布关于CRTP问题,谢谢.

c++ oop crtp vtable

5
推荐指数
2
解决办法
1600
查看次数

对vtable的未定义引用

我正在尝试编写一个基本上像indianwebproxy一样工作的Http代理

所以我启动了qtcreator,但是我的一个类无法使用臭名昭着的错误进行编译:undefined reference to vtable for HttpProxyThreadBrowser.我无法弄清楚为什么这样做.我在Stackoverflow上阅读了类似的问题,显然问题是未定义的虚拟方法不纯,但我还没有声明任何虚函数.这是我的课

class HttpProxyThreadBrowser : public QThread
{
public:
    HttpProxyThreadBrowser(QTcpSocket outgoingSocket,QTcpSocket  browserSocket,QObject *parent = 0);
    ~HttpProxyThreadBrowser(){};
    void run();

private:
    QTcpSocket outgoingSocket;
    QTcpSocket browserSocket;

};
Run Code Online (Sandbox Code Playgroud)

我在这里用pastebin定义了这个类,以免给你带来烦恼.不幸的是,我无法找出为什么vtable未定义.请协助.

httpproxythreadbrowser.cpp:5: undefined reference to `vtable for HttpProxyThreadBrowser
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

c++ qt linker-errors vtable

5
推荐指数
3
解决办法
3万
查看次数

从 VTable 调用 struct 中的非托管函数

是否可以从 C# 调用函数到结构中的非托管函数(通过 VTable)。

例如,我正在挂接一个应用程序,我正在为每个类(应用程序的)重新创建结构。

public struct SomeStruct {
   [FieldOffset(0x00)]
   public IntPtr * VTable;

   [FieldOffset(0x10)]
   public uint SomeValue;
}
Run Code Online (Sandbox Code Playgroud)

然后,我通常这样做:

var * data = (SomeStruct*)(Address);
Run Code Online (Sandbox Code Playgroud)

我希望通过以下任一方式从结构的 VTable 调用函数

Invoke<delegate>(data->VTable[0x3C])(delegateArguments)
Run Code Online (Sandbox Code Playgroud)

或者

var eax = Invoke<Func<uint,uint>(data->VTable[0x3C])(arg1,arg2)
Run Code Online (Sandbox Code Playgroud)

此外,这是否可以有效地完成(因为这些 vtable 函数可以被多次调用)?

也许通过反射发射?

据我所知,每次调用Invoke<>func时,编组都必须创建委托函数。

.net c# unmanaged vtable

5
推荐指数
1
解决办法
839
查看次数

有没有办法转储 g++ 编译程序的类布局

使用 g++ 编译时,-fdump-class-hierarchy 以(或多或少)人类可读格式导出程序的虚表。但是,生成的文件仅包含有关 vtable 的信息,而不包含有关类布局本身的信息。我想获得我所有程序类的布局的完整列表。

clang 提供 -cc1 -fdump-record-layouts 参数来实现这一点。可以使用 -d1reportAllClassLayout 调用 MS 编译器。是否有任何 g++ 开关可以做到这一点?

c++ variables gcc g++ vtable

5
推荐指数
1
解决办法
2298
查看次数

在 C++ 中为虚函数禁用动态绑定(创建虚表)

我最近遇到了一个 C++ 面试问题,这让我很感兴趣:

假设您错误地将某个 C++ 成员函数声明为虚拟函数,但是(可能出于性能原因)您希望阻止编译器为该函数创建 v 表。也就是说,禁用动态函数绑定以支持静态绑定。

你将如何实现这一目标?另外,是否有一些 C++11 特定的方法来这样做?

c++ performance vtable c++11

5
推荐指数
1
解决办法
1452
查看次数

Qt 中运行时“找不到虚拟表的链接器符号...”错误的原因是什么?

这个问题被多次以类似的方式提出,例如在stackoverflowforum.qt.ioqtcentre.org。问题是这个错误消息非常模糊,以至于一种解决方案无法应用于另一种场景。不过,大多数线程都在讨论中死掉了:-(

所以我在 Qt 应用程序中收到的完整错误消息是:

找不到“OneOfMyClasses”
值的虚拟表的链接器符号,而是找到“QString::shared_null”

OneOfMyClasses根据各种情况而变化,QString::shared_null对于我收到的所有错误保持不变。这是我的日志控制台的屏幕截图:

在此输入图像描述

  1. 为什么字体颜色是粉红色的,那么谁在打印这条消息呢?
  2. 为什么只有在设置断点并单步执行代码时才会看到此消息?仅运行应用程序时不会出现此消息。

它发生的点是在当前位置之前的源代码行中的该函数中(黄色箭头):

在此输入图像描述

因此,根据我进入的消息m_pStateWidget->insertNavLabel(...),错误消息打印在与 QString 类相关的 Qt 内的构造函数中的某个位置。所以我尝试了以下方法,将问题从该代码位置移开:

在此输入图像描述

执行此操作时,我在下面的几行代码中收到相同的错误消息,消息中包含另一个类名,请注意 QString ::shared_null保持不变。

在我看来,我的记忆有某种损坏。

  1. 我应该如何开始调查这个问题?我害怕更改代码,因为这可能会隐藏如上所述的问题。
  2. QString::shared_null 是怎么回事?我发现其他人经常在错误消息中看到相同的内容。

感谢您的任何提示或帮助!:-)

编辑:现在变得非常有趣。在打印消息之前我已经进入了每个函数,最终得到了这些错误消息:

在此输入图像描述

在这个位置:

在此输入图像描述

当我在 QtCreator 中浏览调用堆栈时,每次我在堆栈中选择另一个函数时,都会一次又一次地打印错误。

  1. 这是否意味着调试器正在打印消息,并且它太愚蠢了,无法为我解决某种 vtable 问题,或者这是否意味着我遇到了严重的问题?

c++ linker qt vtable

5
推荐指数
1
解决办法
5328
查看次数

如果没有类重新实现“virtual”关键字,是否可以优化它?

当我在 C++ 中定义类时,我总是将 dtor 定义为 virtual。这是我保护自己的方法,以防我编写继承类。

我想知道即使我不会继承该类,我是否也要支付性能开销。

例如:

class A final
{
    A();
    virtual ~A(){printf("dtor");}
};
Run Code Online (Sandbox Code Playgroud)

当我使用此类时,dtor 实际上会通过 vtable 调用还是会作为静态 dtor 实现?

c++ virtual inheritance vtable

5
推荐指数
1
解决办法
127
查看次数

如何在运行时检测C++对象指向vtable的指针的修改?

令 vptr 为指向 vtable 的指针,该 vtable 随其类受虚拟函数约束的对象一起携带。

“vptr”的改变可能不是预期的行为。然而,这种更改不能被检测为非法内存访问,因为指针位于已分配内存的边界内。据我所知,“Efence”和“valgrind/memcheck”不会有帮助。

然而,意外的 vptr 更改可能会导致严重的问题。如果 vptr 被更改为指向任意内存,则删除运算符可能会立即导致分段错误。

是否有任何东西可以在 vtable 或指向 vtable 的指针上设置“守卫”,以便监视任何更改?

Clang++ 似乎并没有完成全部工作。给定

#include <string.h>
#include <stdio.h>
struct X { virtual ~X() {} };
int main(int argc, char** argv)
{
    X x;
    memset((void*)&x, 0, sizeof(X));
    printf("<before exit>\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译并执行...

> clang++ -fsanitize=undefined -fsanitize=vptr tmp.cpp -o test
> ./test
Run Code Online (Sandbox Code Playgroud)

在调用“virtual ~X()”时检测违规行为。

<before exit>
<unknown>: runtime error: member call on address 0xbfe30ab8 which does not point to an object of type 'X' …
Run Code Online (Sandbox Code Playgroud)

c++ gdb valgrind vtable address-sanitizer

5
推荐指数
0
解决办法
1032
查看次数

将实现注入单个多功能接口类 - 许多 CRTP 类?

如何创建多个类来充当接口类的实现者,同时尽可能避免 v-table 成本,并且仍然启用对接口的静态转换?

对于一个简单的情况,它可以像下面的例子一样实现。

例子

图书馆代码:-

class I{ //interface
    public: virtual void i1()=0;
};
template<class Derived>class Router : public I{ 
    public: virtual void  i1()final{   
        //in real case it is very complex, but in the core is calling :-
        static_cast<Derived*>(this)->u1(); 
    }
};
Run Code Online (Sandbox Code Playgroud)

用户代码:-

class User : public Router<User>{
    public: void u1(){ std::cout<<"hi"<<std::endl; }
};
int main() {
    User u;
    u.i1();   //<-- no v-table cost
    I* i=&u;
    i->i1();  //<-- has v-table cost (OK)
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

完整演示

如何扩展上述功能以支持 2 …

c++ interface crtp vtable c++14

5
推荐指数
1
解决办法
207
查看次数

成员结构位域元素的初始化列表初始化导致 IAR ARM 中的错误

我在 IAR 中有以下类结构:

class A
{
public:
    A(){}
    virtual ~A() {};
    virtual void load() {};
};


class C
{
public:
    C()
    {
        //C does other stuff, not relevant
    }
};

class D;

class B : public A
{
public:
    B() : invert(false) {};
    virtual ~B() {};
    void load()
    {
        //Irrelevant stuff done here
    }
private:
    C member_c;
    std::vector<D*> vector_of_d;
    struct {
        bool var_1:1;
        bool var_2:1;
        bool var_3:1;
        bool var_4:1;
        bool invert:1;
    };
};
Run Code Online (Sandbox Code Playgroud)

我遇到了为初始化 B 而生成的程序集的错误,它似乎对 VTable 指针的位置与匿名结构位域的位置感到“困惑”。当它设置反转位为假时,它转到对象的第一个字(即 VTable 指针)并翻转地址中的一个位。当我稍后调用 …

c++ arm vtable iar bit-fields

5
推荐指数
1
解决办法
261
查看次数