You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用asmjit库通过汇编调用C++非静态成员函数的问题咨询

非静态成员函数asmjit调用方案

能否通过名称直接调用?

不建议通过名称调用非静态成员函数。你观察到的_ZNK3Foo5printEv是clang遵循Itanium C++ ABI生成的修饰名,命名规则和类名、函数签名、const/volatile修饰、命名空间层级强绑定,只要类结构、函数参数或修饰符有变动,修饰名就会变更,硬编码修饰名的稳定性极差,维护成本非常高。

获取非静态成员函数地址的可行方案

直接在宿主代码中取成员函数指针并提取入口地址是最优方案,完全绕开名称修饰问题:

  • 对于非虚成员函数,直接通过C++语法取函数指针,提取实际入口地址即可:
    class Foo {
    public:
        void print() const;
    };
    
    // 取非静态成员函数指针
    void (Foo::*memberFunc)() const = &Foo::print;
    // Itanium ABI下非虚成员函数指针的前8字节即为实际函数入口地址
    uint64_t funcEntry = *reinterpret_cast<uint64_t*>(&memberFunc);
    
    你拿到funcEntry之后直接作为asmjit中call指令的目标地址即可,调用时按x86_64 System V ABI将实例地址传入rdi寄存器,和你之前调用全局函数的逻辑完全一致。
  • 对于虚成员函数,不要直接取类的成员函数指针,要通过实例的虚表动态查询地址:
    Foo* fooInstance = new Foo();
    // 实例首地址存储虚表指针
    uintptr_t* vtable = *reinterpret_cast<uintptr_t**>(fooInstance);
    // 按虚函数在类中的声明顺序取对应索引的地址,比如print是第一个虚函数就取索引0
    uint64_t funcEntry = vtable[0];
    

如果你确实有动态按名称查找的需求,可以在编译宿主程序时添加-rdynamic参数导出符号表,再通过dlsym接口查找对应修饰名的地址,但该方案稳定性低,除非必要不建议使用。

内容的提问来源于stack exchange,提问作者jagemue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:06:05