加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – 强制类型SWIG

发布时间:2020-12-13 18:02:50 所属栏目:PHP教程 来源:网络整理
导读:所以我有以下C #include stdio.h#include iostream#include vectorusing namespace std;int hello(char *str);int hello(char *str) { cout "Hello World: " str endl; return 0;} 以及swig接口 %module sphp%{extern int hello(char *str);%}extern int hel
所以我有以下C
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;

int hello(char *str);

int hello(char *str) {
    cout << "Hello World: " << str << endl;
    return 0;
}

以及swig接口

%module sphp

%{
extern int hello(char *str);
%}

extern int hello(char *str);

我可以在php中编译和使用它,

php> hello("testing!");

这一切都是邪恶的!

唯一的问题是

php> hello(3);

仍然有效.我不想要这个,似乎默默无闻地投下了类型

/*@SWIG:/usr/share/swig2.0/php/utils.i,62,CONVERT_STRING_IN@*/
  if ((*args[0])->type==IS_NULL) {
    arg1 = (char *) 0;
  } else {
    convert_to_string_ex(args[0]);
    arg1 = (char *) Z_STRVAL_PP(args[0]);
  }
  /*@SWIG@*/;

现在我不想编辑包装器,因为它是自动生成的.有没有办法可以关闭这个静默转换,这样hello(3)会抛出异常或错误,或者我可以给一个关于它最初传递的php参数类型的提示吗?

遗憾的是,由于包装器的生成方式,您无法完全摆脱铸件.
但是,您可以拦截基本数据类型并将它们重定向到模板函数,如下所示:
%module sphp

%{
  #include <iostream>

  extern int hello(char *str);

  template<class T> 
  int hello(const T &)
  {
    std::cout << "unsupported data type" << std::endl; 
  }
%}

extern int hello(char *str);

template<class T> 
int hello(const T &);

%template(hello) hello<int>;

要拦截更多数据类型,只需添加一个新的运算符重载:

%template(hello) hello<double>;

更新:

这是一个更加困难的方法,可以通过覆盖SWIG的typemaps来实现.这取自SWIG的PHP类型映射并进行修改以防止它转换值.

%module sphp

%{
  extern int hello(char *str);
%}

%typemap(in) char *
{
  if ((*$input)->type != IS_STRING)
    SWIG_PHP_Error(E_ERROR,"Type error in argument $argnum of $symname. Expected string");
   $1 = ($1_ltype) Z_STRVAL_PP($input);
}

%typemap(in) (char *STRING,int LENGTH),(char *STRING,size_t LENGTH) {
  if ((*$input)->type != IS_STRING)
    SWIG_PHP_Error(E_ERROR,"Type error in argument $argnum of $symname. Expected string");
   $1 = ($1_ltype) Z_STRVAL_PP($input);
   $2 = ($2_ltype) Z_STRLEN_PP($input);
}

extern int hello(char *str);

输出:

php > include ("sphp.php");
php > hello("test");
Hello World: test
php > hello(3);
PHP Fatal error:  Type error in argument 1 of hello. Expected string in php shell code on line 1
php > hello([]);
PHP Fatal error:  Type error in argument 1 of hello. Expected string in php shell code on line 1
php >

这更加乏味,因为如果你想完全摆脱自动参数转换,你必须以相同的方式覆盖每一种类型,另一方面它可以让你更好地控制参数转发的行为.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读