实施SWIG类型

 fuckyourgirlfriend 发布于 2023-02-07 14:42

所以我有以下C++

#include 
#include 
#include 
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)就会抛出异常或错误,或者我可以提一下hello它最初传递的php参数的类型吗?

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

    %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的类型图来实现的方法.这取自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 > 
    

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

    2023-02-07 14:44 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有