gpt4 book ai didi

php - 在PHP扩展中,推荐的方法从and std::string返回值

转载 作者:搜寻专家 更新时间:2023-10-31 02:06:19 25 4
gpt4 key购买 nike

我们有一个简单的PHP函数,其目的是调用一个C++自由函数std::string callLibrary(std::string)并返回其std::string返回值。

当前看起来像这样:

PHP_FUNCTION(call_library)
{
char *arg = NULL;
size_t arg_len, len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE)
{
return;
}

// Call underlying library
std::string callResult = callLibrary(arg);
zend_string * result = zend_string_init(callResult.c_str(), callResult.size(), 0);
RETURN_STR(result);
}

我们找不到描述 zend_string_initRETURN_STR()行为的引用手册,这是我们最近的事情:
http://www.phpinternalsbook.com/php7/internal_types/strings/zend_strings.html

特别是,它声明了 zend_string_init的最后一个参数

If you pass 0, you ask the engine to use a request-bound heap allocation using the Zend Memory Manager. Such allocation will be destroyed at the end of the current request. If you don’t do it yourself, on a debug build, the engine will shout at you about a memory leak you just created. If you pass 1, you ask for what we called a “persistent” allocation, that is the engine will use a traditional C malloc() call and will not track the memory allocation in any way.



似乎我们需要 0值,但是 RETURN_STR()是否可以释放分配的内存? (文本有点模棱两可,但似乎破坏应该是明确的)
是否有更惯用的方法从PHP扩展函数返回此类 std::string值?

最佳答案

为了回答您的问题,我将简单介绍一下PHP内存分配,然后再讨论您的特定问题。

关于PHP内存分配

编写PHP扩展时,可以执行两种内存分配:

  • 跟踪内存分配
  • 持久内存分配

  • 跟踪的内存分配是一种优化,它允许PHP引擎对原始内存分配进行更多控制。 Zend内存管理器(ZendMM)充当标准内存分配库之上的包装器。该内存管理器允许PHP通过清除所有在请求结束时未明确释放的跟踪内存来避免内存泄漏。此外,这允许引擎制定内存限制(例如 php.ini设置 memory_limit )。由于这些原因,跟踪的内存也称为每个请求的内存。

    持久性内存分配是由C库管理的标准内存分配(例如 malloc和friends)。还值得注意的是,在C++中, newdelete通常分别调用 mallocfree。在PHP中,持久性内存分配在处理一个请求后仍然存在,并且可能存在以服务多个请求。因此,使用这种分配可能导致内存泄漏。

    在PHP API中,定义了一些宏以执行跟踪的或持久的内存分配。例如, emallocefreemallocfree的类似物,用于跟踪(即每个请求)的内存管理。宏 pemallocpefree用于跟踪分配或持久分配,具有可切换的参数。例如, pemalloc(32,1)分配32个持久性字节的块,而 pemalloc(32,0)等效于 emalloc(32)分配32个跟踪字节的块。

    除了原始内存分配功能外,PHP API还提供了对由更高级别功能启动的内存分配的控制。例如,使用 zend_string创建一个PHP7 zend_string_init结构可让您通过第三个参数选择所需的内存分配类型。这遵循整个API的通用习惯用法, 0指示跟踪的分配, 1指示持久性的分配。

    关于zend_stringzend_string_initRETURN_STR

    我对PHP7的了解不如对PHP5的熟悉,但是许多概念已经延续了下来,我认为我已经阅读了足够的源代码来回答这个问题。当您使用 zend_stringzval分配给 RETURN_STR时, zval负责释放 zend_string(在PHP5中,这只是 char*,但概念相同)。 Zend引擎期望使用跟踪的内存管理器分配大多数(如果不是全部)对象。在PHP5中,必须通过 zval分配分配给 emalloc的字符串,因为当 efree被销毁时,该代码总是在字符串缓冲区上调用 zval。在PHP7中似乎有 an exception,因为 zend_string结构可以记住使用了哪种分配类型。无论如何,除非有充分的理由,否则始终将跟踪的分配用作默认值是一个好习惯。因此,您当前的代码看起来不错,因为它将 0作为第三个参数传递给 zend_string_init
    zend_string的销毁不应在您的代码中明确显示,因为 zval将在以后的某个时间进行处理。另外,该过程取决于用户空间如何对返回的 zval进行操作。这不是您不必担心的事情。

    关于php - 在PHP扩展中,推荐的方法从and std::string返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50465101/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com