所以我有以下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参数的类型吗?
可悲的是,由于包装器的生成方式,你无法完全摆脱铸件.但是,您可以拦截基本数据类型并将它们重定向到模板函数,如下所示:
%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 >
如果你想完全摆脱自动参数转换,你必须以相同的方式覆盖每一种类型,这更加乏味,另一方面它可以让你更好地控制参数转发的行为.