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

C++编写第三方库桩代码报cannot declare pointer to ‘void’ member错误

问题场景

项目引入第三方库及配套头文件,开发完成进入单元测试阶段,需要编写桩(stub)库替代原第三方库。
第三方库头文件中定义的结构体如下:

typedef struct{
    int (*init)(int * var);
    void (*close)(void);
} AInterface;

编写桩代码时先后尝试两种实现均编译失败,具体错误如下:

第一种错误实现

int AInterface::*init(int* var)
{
    return 0;
}

void AInterface::*close(void)
{}

编译报错:

stub.cpp:76:33: error: cannot declare pointer to ‘void’ member
void AInterface::*close(void)

第二种错误实现

int initAInterface(int * var);

int (AInterface::*init)(int * var) = &initAInterface;

int initAInterface(int* var)
{
    return 0;
}

编译报错:

error: cannot convert ‘int ()(int)’ to ‘int (AInterface::)(int)’ in initialization
int (AInterface::init)(int var) = &initAInterface;

补充说明:桩代码.cpp文件中未定义main函数。
核心疑问:

  • 上述实现的错误点是什么?
  • 正确的桩代码实现方式是什么?

错误原因
  1. 第一种实现的本质是语法认知错误
    AInterface是C风格结构体,其中的init、close是普通函数指针类型的成员变量,不是C++类的成员函数,不存在需要在外部实现的AInterface::init、AInterface::close成员函数实体。写法中用到的AInterface::*语法是用来声明指向类成员的指针,和结构体里的函数指针成员完全无关,属于语法误用。
  2. 第二种实现的本质是类型不匹配
    声明的int (AInterface::*init)(int*)是指向AInterface类成员函数的指针,这类指针自带隐式this指针参数,调用约定、内存布局和普通全局函数完全不同,和普通全局函数initAInterface的指针类型int (*)(int*)不兼容,无法直接转换赋值。

两种错误的核心根源是:误将结构体里的C风格函数指针成员,当成了C++类的成员函数来实现。


正确实现方式

C风格结构体里的函数指针本质就是存储函数地址的变量,只需要实现对应签名的普通桩函数,再把桩函数的地址赋值给对应结构体实例的函数指针成员即可,不需要做“成员函数实现”。
根据原第三方库的导出形式,分两种常见实现:

场景1:原库通过接口函数返回AInterface实例

#include "third_party_header.h"

// 实现符合签名的桩函数
static int stub_init(int* var)
{
    // 自定义桩逻辑,例如返回测试预期值、打日志等
    if (var) *var = 1;
    return 0;
}

static void stub_close(void)
{
    // 自定义桩逻辑
    return;
}

// 加extern "C"避免C++符号名改编,保证和原库导出符号一致
extern "C" AInterface* get_a_interface()
{
    static AInterface stub_inst = {
        .init = stub_init,
        .close = stub_close
    };
    return &stub_inst;
}

场景2:原库直接导出AInterface类型的全局实例

#include "third_party_header.h"

static int stub_init(int* var) { return 0; }
static void stub_close(void) {}

// 全局变量名和原库导出的符号名保持一致即可
extern "C" AInterface g_a_interface = {
    .init = stub_init,
    .close = stub_close
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:18:17