将 vector<std::string> 转换为本机 PHP 数组
Swig convert vector<std::string> to native PHP array
我开始使用swig
和php
,并且我想将std::vector<std::string>
返回到我的php
代码。我试过这个(所有的编译工作)。
我的swig文件:
%module example
%include <std_string.i>
%include <std_vector.i>
%{
extern std::vector<std::string> testSwig(const char *path);
%}
//try here to convert vector to native php array
%typemap(out) const std::vector<std::string> & {
array_init($result);
Array::const_iterator i = $1->begin();
Array::const_iterator e = $1->end();
for(; i != e; ++i ) {
zval * data;
MAKE_STD_ZVAL(data);
ZVAL_STRINGL(data, (char*)i->c_str(), i->size(), 1);
zend_hash_next_index_insert( HASH_OF($result), &data, sizeof(zval *), NULL );
}
}
extern std::vector<std::string> testSwig(const char *path);
my CPP file:
#include <iostream>
#include <vector>
std::vector<std::string> testSwig(const char *path)
{
std::vector<std::string> v;
v.push_back("test 1");
v.push_back("test 2");
v.push_back("try vector");
return v;
}
最后是我的php文件:
<?php
echo '<pre>';
echo print_r(testSwig('try arg'));
echo '</pre>';
?>
我的问题是,我的转换std::vector
到php
数组不工作;当我制作print_r
时,我得到了这个结果:resource(1) of type (_p_std__vectorT_std__string_t)
将Flexo提供的答案加起来。
在PHP7 zend API MAKE_STD_ZVAL()宏被删除(包括一些其他的东西:https://wiki.php.net/phpng-upgrading)
为了使这个typemap在PHP7中工作,我做了下面的工作:
%typemap(out) std::vector<std::string> {
array_init($result);
$1_type::const_iterator i = $1.begin();
$1_type::const_iterator e = $1.end();
for(; i != e; ++i ) {
add_next_index_string($result, (char*) i->c_str() );
}
}
testSwig函数从php打印的只是期望的:
Array
(
[0] => test 1
[1] => test 2
[2] => try vector
)
您的代码非常接近于工作,但由于类型不匹配而无法正确应用。您的out类型映射被编写为const std::vector<std::string> &
,而您使用的测试函数只是返回std::vector<std::string>
,即不是const,按值返回,而不是按引用返回。
有了这个固定,很明显,在你的代码中没有定义称为Array
的类型,并且$1
实际上是std::vector<std::string>
的实例,而不是指向on的指针。我使用$1_ltype
使SWIG为typemap的输入生成正确的完全限定类型。因此,为了使你的代码工作,我们需要这样修改它:
%module test
%{
#include <string>
#include <vector>
%}
%typemap(out) std::vector<std::string> {
array_init($result);
$1_type::const_iterator i = $1.begin();
$1_type::const_iterator e = $1.end();
for(; i != e; ++i ) {
zval * data;
MAKE_STD_ZVAL(data);
ZVAL_STRINGL(data, (char*)i->c_str(), i->size(), 1);
zend_hash_next_index_insert( HASH_OF($result), &data, sizeof(zval *), NULL );
}
}
%inline %{
std::vector<std::string> testSwig(const char *path)
{
std::vector<std::string> v;
v.push_back("test 1");
v.push_back("test 2");
v.push_back("try vector");
return v;
}
%}
在Ubuntu 14.04和PHP 5上,这足以让下面的测试用例像你希望的那样工作:
<?php
include('test.php');
print_r(test::testSwig('hello'));
?>
我编译并运行为:
swig -php -c++ test.i
g++ test_wrap.cpp $(php-config --includes --libs) -shared -o test.so -fPIC
php5 run.php
Array
(
[0] => test 1
[1] => test 2
[2] => try vector
)
作为参考,SWIG向量和字符串类是非常有用的,给定:
%module test
%include <std_string.i>
%include <std_vector.i>
%template(StringVec) std::vector<std::string>;
%inline %{
std::vector<std::string> testSwig(const char *path)
{
std::vector<std::string> v;
v.push_back("test 1");
v.push_back("test 2");
v.push_back("try vector");
return v;
}
%}
类型StringVec
是正常的,无需进一步操作即可使用。
- 从C++本机插件更新Vector3数组
- GCC本机矩阵运算库
- VC++本机单元测试,找不到调试符号
- 在这种情况下,java对象是否可以调用本机函数
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 无法将标准库导入本机 android 项目中的头文件
- 使用本机 C++ 应用程序中的 C# 代码
- 在nodejs中使用本机代码的最佳方法是什么?
- 如何告诉本机节点模块所需的dll存储在哪里?
- 在自定义程序中使用本机 Windows 自然顺序排序
- 如何在C++非托管/本机 DLL 中从注册免费 COM C# 托管 DLL 创建 COM 对象
- MS 本机单元测试 - 断言::线程失败不起作用
- 将音频从浏览器流式传输到WebRTC本机C++应用程序
- Winapi - SetWindowLongPtr in ShutdownBlockReason创建/销毁JNI本机代码
- C++/CLI 混合托管/本机 DLL 不起作用
- 子系统中的异常处理:本机
- 多次调用本机方法时出现致命错误
- 如何使用 Malloc 调试来检查本机内存泄漏?
- 将 vector<std::string> 转换为本机 PHP 数组