c++ - 在 OSX 上替换 libstdc++.dylib (4.0) 全局新建和删除运算符

标签 c++ xcode gcc stl new-operator

我正在努力用 XCode 3.2、GCC 4.2、libstdc++ 4.0、动态版本替换全局的 new 和 delete 运算符。

我直接从 header “new”中获取原型(prototype)并实现它们。它们粘贴在下面。

该项目是一个 .plugin,因此是一个动态库。此插件必须将分配委托(delegate)给主应用程序自己的 alloc/free 例程,这些例程位于旧的 C SDK 中。

我自己对 new/delete 的所有调用以及 std::list 和 std::map 分配都被正确替换,但不是在 std::vector::push_back 必须增加其缓冲区时。在这种情况下,我的 operator new 不会被调用,但我的 operator delete 会被调用。我知道这一点,因为我在我的新运算符(operator)分配的任何缓冲区的前四个字节中写了一个标记,并且我在运算符(operator)删除中检查了这个标记。请参阅下面的违规代码。

extern "C++"
{
__attribute__((visibility("default"))) void* operator new(std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void* operator new[](std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void operator delete(void*) throw();
__attribute__((visibility("default"))) void operator delete[](void*) throw();
__attribute__((visibility("default"))) void* operator new(std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void* operator new[](std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete(void*, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete[](void*, const std::nothrow_t&) throw();

}

以下代码将在“yo”超出范围时引发断言,因为为 std::vector 分配的内存不是由我的 operator new 分配的。

   {
        std::vector<std::string> yo;
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
    }

下面的代码是可以的,因为 std::vector::reserve 调用了我的 operator new:

   {
        std::vector<std::string> yo;
        yo.reserve(4);
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
    }

GBD(调试器)在需要增大缓冲区时不会让 met 进入 std::vector::push_back 实现(该方法名为 _M_insert_aux)。我所知道的是,从未从 std::vector::push_back 调用我的 operator new。

上述解决方法不能应用于我正在使用的所有第 3 方库。其中之一是 push_back 的大用户。

我尝试静态链接到 libstdc++.a,但我遇到了同样的问题。

是否有一些不使用全局 new 运算符的 std::vector< std::string > 特化?

顺便说一句,这在带有 VS9 的 Windows 上完美运行。

最佳答案

我终于通过使用 George Costanza 的技术解决了我的问题:反其道而行之。

我没有尝试让我的运算符成为新的和删除可见的,而是完全隐藏了它们。

诀窍是在每个静态库和包设置中设置这些:

  • 设置 C++ 标准库类型:静态
  • 默认隐藏的符号:选中
  • 修复并继续:未选中(非常重要,否则静默禁用以前的设置)

并进行清理所有和构建,因为在 XCode 3.2 中,仅在更改这些设置后点击构建是行不通的。

显然,我将 operator new & delete 原型(prototype)更改为:

#pragma GCC visibility push(hidden)

extern "C++"
{
    void* operator new(std::size_t) throw (std::bad_alloc);
    void* operator new[](std::size_t) throw (std::bad_alloc);
    void operator delete(void*) throw();
    void operator delete[](void*) throw();
    void* operator new(std::size_t, const std::nothrow_t&) throw();
    void* operator new[](std::size_t, const std::nothrow_t&) throw();
    void operator delete(void*, const std::nothrow_t&) throw();
    void operator delete[](void*, const std::nothrow_t&) throw();
} // extern "C++"

#pragma GCC visibility pop

不,为什么会这样?必须同时具有静态和隐藏符号才能工作。它似乎使我的捆绑插件免受内联其分配器的 STL 特化实现的影响。

另请注意,这只发生在从大型应用程序动态加载的捆绑插件中。在从控制台应用程序调用的一个简单的 .dylib 项目中,一切都可以在任何设置下正常工作。

关于c++ - 在 OSX 上替换 libstdc++.dylib (4.0) 全局新建和删除运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3472020/

相关文章:

c++ - boost.serialization 并替换现有的序列化 std::wstring 的方法

c++ - 使用 "this"指针和不使用它有区别吗?

iPhone - 如何关闭屏幕并继续播放视频?

ios - 为什么显示 Google 插页式广告会改变我的导航栏的高度? Xcode 11.3、iOS 13

c++ - int64_t 背后的魔力是什么

c# - C++ MFC 与 .NET?

c++ - QDataWidgetMapper 中未提交更改时如何通知用户

ios - 找不到Ionic 3应用程式的'Branch.h'文件Xcode错误

c - 如何让 GCC 在没有内置函数的情况下为大端存储生成 bswap 指令?

c++ - 等效的 gcc 程序集?