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