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