g ++用户定义的动态链接库上的全局new和delete运算符

Posted

技术标签:

【中文标题】g ++用户定义的动态链接库上的全局new和delete运算符【英文标题】:g++ user-defined global new and delete operators on dynamically linked libraries 【发布时间】:2020-02-17 13:52:44 【问题描述】:

在 g++ 上,来自动态链接库的代码使用主程序中的 operator delete。 使用-Wl,-Bsymbolic 选项,动态链接库使用它自己的运算符new,但使用主程序的运算符delete。 使用带有-Wl,-Bsymbolic 选项的clang++ 进行编译具有使用其自己的运算符new 和delete 的动态链接库。 在 Linux (ubuntu) 上

// base_program.cpp
#include <dlfcn.h>
#include <stdio.h>
#include <cstdlib>
typedef void dllFunc();

void *operator new(std::size_t count) 
    printf("base_program new\n");
    void *result = malloc(count);
    return result;

void *operator new[](std::size_t count) 
    printf("base_program new[]\n");
    void *result = malloc(count);
    return result;

void operator delete(void *ptr) noexcept 
    printf("base_program delete\n");
    free(ptr);

void operator delete[](void *ptr) noexcept 
    printf("base_program delete[]\n");
    free(ptr);


int main(int nArgs, char **args) 
    void *handle = dlopen(DLLFILE, RTLD_LAZY);
    dllFunc *func = (dllFunc*) dlsym(handle, "testFunc");
    printf("Linking with %s\n", DLLFILE);
    int *a = new int;
    delete a;
    func();
    printf("\n");
    return 0;

// linking.cpp
#include <stdio.h>
#include <cstdlib>
void *operator new(std::size_t count) 
    printf("linking new\n");
    void *result = malloc(count);
    return result;

void *operator new[](std::size_t count) 
    printf("linking new[]\n");
    void *result = malloc(count);
    return result;

void operator delete(void *ptr) noexcept 
    printf("linking delete\n");
    free(ptr);

void operator delete[](void *ptr) noexcept 
    printf("linking delete[]\n");
    free(ptr);


extern "C" void testFunc() 
    int *a = new int;
    delete a;

// build.sh
g++ -g -fPIC -DDLLFILE="\"linking_g.so\"" base_program.cpp -o base_program_g -ldl
g++ -g -fPIC -shared linking.cpp -o linking_g.so -Wl,-Bsymbolic

clang++ -g -fPIC -DDLLFILE="\"linking_clang.so\"" base_program.cpp -o base_program_clang -ldl
clang++ -g -fPIC -shared linking.cpp -o linking_clang.so -Wl,-Bsymbolic

运行 ./build.sh; ./base_program_g; ./base_program_clang 会导致以下结果

Linking with linking_g.so
base_program new
base_program delete
linking new
base_program delete

Linking with linking_clang.so
base_program new
base_program delete
linking new
linking delete


如何在 g++ 中获得 clang++ 行为?

【问题讨论】:

【参考方案1】:

operator delete 在不同的 C++ 标准中有不同的声明。您使用 noexcept 的定义需要 C++11。

您可能使用的是旧的g++ 版本,默认情况下以 C++03 方言编译。

解决方法是在命令行上显式设置 C++11 或更新的标准。我用-std=gnu++11 进行了测试,它解决了你的问题。

【讨论】:

我再次检查,--std=gnu++11 工作,但它停止工作 --std=gnu++14--std=gnu++17 @CalvinKu 请注意,此选项有一个破折号,例如-std=... 不是 --std=... @CalvinKu 您的构建脚本忽略了失败。确保你重建你的来源。

以上是关于g ++用户定义的动态链接库上的全局new和delete运算符的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 动态链接没有与自定义标签上的短 URL 进行深度链接

管理页面上的动态字段 - Postgres 和 MongoDB

重新定义 MS Access 文件和 SQL Server 之间的数据链接

PHP基础-PHP中预定义的超全局数组

将标签和图像动态添加到 Android 中的自定义视图

vue2.0 全局变量怎么设置