Принудительно применять SWIG

Итак, у меня есть следующий 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,[email protected]*/
  if ((*args[0])->type==IS_NULL) {
    arg1 = (char *) 0;
  } else {
    convert_to_string_ex(args[0]);
    arg1 = (char *) Z_STRVAL_PP(args[0]);
  }
  /*@[email protected]*/;

Теперь я не хочу редактировать обертку, потому что она генерируется автоматически. Есть ли способ отключить это тихое преобразование, чтобы hello(3) выдавало исключения или ошибки, или я могу дать hello подсказка о типе аргумента php, который был передан изначально?

7 голосов | спросил Jakob Bowyer 30 MonEurope/Moscow2013-12-30T20:08:47+04:00Europe/Moscow12bEurope/MoscowMon, 30 Dec 2013 20:08:47 +0400 2013, 20:08:47

1 ответ


0

К сожалению, из-за того, как создается оболочка, вы не можете полностью избавиться от кастинга. Однако вы можете перехватить основные типы данных и перенаправить их в шаблонную функцию следующим образом:

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

Update:

Вот более сложный подход, который работает, переопределяя шрифты SWIG . Это взято из PHP-карт типов SWIG и изменено, чтобы не приводить к приведению значений.

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

Это более утомительно, поскольку вам придется переопределять каждый отдельный тип одинаковым образом, если вы хотите полностью избавиться от автоматического приведения аргументов, с другой стороны, это дает вам больший контроль над поведением пересылки аргументов.

ответил voodooattack 2 Jpm1000000pmThu, 02 Jan 2014 22:28:39 +040014 2014, 22:28:39

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132