2016-11-09 31 views
1

我开始swigphp工作,我想返回std::vector<std::string>php code.I有试试这个(所有的编译工作)。痛饮转换矢量<std::string>原生PHP数组

我痛饮文件:

%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); 

我的cpp文件:

#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; 
} 

而且finaly我的PHP文件来试试这个:

<?php 
    echo '<pre>'; 
    echo print_r(testSwig('try arg')); 
    echo '</pre>'; 
?> 

我的问题是,我的转换std::vectorphp数组不起作用;当我使我的print_r我有这样的结果:resource(1) of type (_p_std__vectorT_std__string_t)

+0

您定位的是哪个版本的PHP? – Flexo

+0

PHP版本5.6 @Flexo – simon

回答

0

你的代码是非常接近工作,但它没有得到正确应用,因为类型不匹配。你输出的类型图被写为const std::vector<std::string> &,而你使用的测试函数只是返回std::vector<std::string>,即不是const和值,而不是引用。

随着该固定的,那么很明显,有在代码称为Array没有定义类型,以及$1实际上是std::vector<std::string>一个实例,而不是一个指向上。我使用$1_ltype使SWIG为typemap的输入生成正确的完全限定类型。因此,为了使你的代码的工作,我们需要这样修改:在PHP 5中,你希望足以让下面的测试情况下工作

%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 
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是理智的,可以使用没有进一步的工作。