Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何将Rust中的整数转换为C中的char*_Php_C_Rust_Ffi - Fatal编程技术网

Php 如何将Rust中的整数转换为C中的char*

Php 如何将Rust中的整数转换为C中的char*,php,c,rust,ffi,Php,C,Rust,Ffi,我有以下用例。C中的结构如下所示: typedef struct _zend_internal_arg_info { const char *name; zend_type type; zend_uchar pass_by_reference; zend_bool is_variadic; } zend_internal_arg_info; (const char*)(unsigned long int)(1) 通常,name字段包含函数名。但由于内部实现,此

我有以下用例。C中的结构如下所示:

typedef struct _zend_internal_arg_info {
    const char *name;
    zend_type type;
    zend_uchar pass_by_reference;
    zend_bool is_variadic;
} zend_internal_arg_info;
(const char*)(unsigned long int)(1)
通常,
name
字段包含函数名。但由于内部实现,此字段也可以携带整数。在C端,有一个宏执行如下铸造:

typedef struct _zend_internal_arg_info {
    const char *name;
    zend_type type;
    zend_uchar pass_by_reference;
    zend_bool is_variadic;
} zend_internal_arg_info;
(const char*)(unsigned long int)(1)
我想做的是在生锈的一端做同样的铸造。我最终得到了以下代码:

fn create_null_argument(required_args: u8, return_reference: bool) -> ZendFunctionArgument {
    let required_args_ref = Box::into_raw(Box::new(required_args as i8)) as *const i8;
    ZendFunctionArgument {
        arg: php_bindings::_zend_internal_arg_info {
            name: required_args_ref,
            type_: 0,
            pass_by_reference: if return_reference { 1 } else { 0 },
            is_variadic: 0,
        },
    }
}
这似乎适用于以下测试:

let arguments_ptr = ZendFunctionArguments::new(5, true).into_raw();
unsafe {
    let arguments: Vec<php_bindings::_zend_internal_arg_info> = Vec::from_raw_parts(arguments_ptr as *mut _, 1, 1);
    let required_args = *arguments[0].name;
    assert_eq!(5, required_args);
}
这里是一个未使用的结构,其中包含对该扭曲逻辑的一些描述:

/* the following structure repeats the layout of zend_internal_arg_info,
 * but its fields have different meaning. It's used as the first element of
 * arg_info array to define properties of internal functions.
 * It's also used for the return type.
 */
typedef struct _zend_internal_function_info {
    zend_uintptr_t required_num_args;
    zend_type type;
    zend_bool return_reference;
    zend_bool _is_variadic;
} zend_internal_function_info;
下面是c中常用的整个宏:

#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args)  \
    static const zend_internal_arg_info name[] = { \
        { (const char*)(zend_uintptr_t)(required_num_args), 0, return_reference, 0 },
zend_uintpttr\t
是:

typedef uintptr_t zend_uintptr_t;
然后:

typedef unsigned long int   uintptr_t;
结构:

pub struct ZendFunctionArgument {
    arg: php_bindings::_zend_internal_arg_info,
}

您的代码是而不是将整数转换为指针-正如Stargateur在评论中所说的,正确的方法更简单
必需的参数为*const::std::os::raw::c_char

相反,您正在使用
Box::new
在堆上分配
必需的参数,然后使用
将其从内存管理器的手中转移到原始的
——给出一个指向
必需的参数值的指针,在您手动清理它之前,它将永远存在

这似乎适用于以下测试

因为您正在通过执行
*参数[0].name将指针解引用到堆中,而该指针处的值实际上是
5

不幸的是,在PHP端(代码执行时),每次执行时,值都是完全随机的


这并不奇怪。由于代码的最终结果是字段的值只是堆中的某个指针,因此每次运行代码时它都会更改

您的代码是而不是将整数转换为指针-正如Stargateur在评论中所说的那样,正确的方法是更简单地
必需的参数*const::std::os::raw::c_char

相反,您正在使用
Box::new
在堆上分配
必需的参数,然后使用
将其从内存管理器的手中转移到原始的
——给出一个指向
必需的参数值的指针,在您手动清理它之前,它将永远存在

这似乎适用于以下测试

因为您正在通过执行
*参数[0].name将指针解引用到堆中,而该指针处的值实际上是
5

不幸的是,在PHP端(代码执行时),每次执行时,值都是完全随机的


这并不奇怪。由于代码的最终结果是字段的值只是堆中的某个指针,因此每次运行代码时它都会更改

(const char*)(unsigned long int)(1)
这在C
ZendFunctionArgument
中没有任何意义,请包含此结构的Rust定义。也许您只是希望此
将x=1设为*const i8
但这仍然没有意义。应该
名称
真的有类型
并集(const char*str;unsigned long integer;}
?@Stargateur我添加了一些详细信息,希望能有所帮助。
(const char*)(unsigned long int)(1)
这在C
ZendFunctionArgument
中没有任何意义,请包含此结构的Rust定义。也许您只是想让x=1作为*const i8;
但这仍然没有意义。应该
name
真正具有类型
并集(const char*str;unsigned long integer;}
?@Stargateur我添加了一些详细信息,希望对您有所帮助。