swig扩展php(二)

2023-05-16

最近需要写一个php扩展,再次想到swig.

以前用过的只是写了一个例子,真的要作起大型的工作来,发现swig虽然强大,但要用明白,还真得多读几遍手册才行。

项目的背景是这样的,有一种DB(具体名字因商业缘故就不说了),它其实是在mysqlCppClinet上包装一层,采用了新的连接方式,但连接后的返回值,就是mysqlcppclient中的connect preparement  resultSet(http://dev.mysql.com/doc/refman/5.1/en/connector-cpp-getting-started-examples.html),所以c++用起来,是平滑的,那么PHP就需要开发一个so.

本来觉得这事儿很简单,既然是c++代码可以简单的用起来,我只要扩展出一个class,返回的是mysqlcppclient中的connect 然后就在php中直接用不就可以了么?但这种思路显然是错的,connect类中的方法,都是c++中的,php怎么可能直接用呢?

那就把connect preparement  resultSet全部包装一遍?又有点量大,何况,connect的具体功能,根本就没必要在PHP中实现,PHP也不应该去调用它,对于PHP来说,它需要的,不就是给个SQL能获取结果吗?所以,最简单的,给出ResultSet 的包装就可以了。

于是写出这样一个.i文件:

%module Td
%{
#include "Td.h"
%}
class Td{
public:

..............................
ResultSet * query(char* sql);
};

.h文件与其类似,.cpp文件也正常的可以编译连接,然后按照正常的顺序:用swig生成_wrap文件,编译_wrap文件,生成so.一切正常,但在php使用时:

<?php 

$r = query("select * from a");

var_dump($r);

?>

这个$r,没有任何方法,也不是一个object,空空的,啥也干不了。

这个问题曾困扰我好久,我一直想不通,它是一个ResultSet型的指针,为什么swig包装后,它不能正常的工作?而如果这个指针指向是我们项目中自定义的一个class,那么它是可以在php中正常使用的。这个问题仍未想通,猜它也许是因为它只是一个指针,swig并不会检查该指针到底是个什么东西,它只会将其包装成SWIGTYPE_p_ResultSet型的指针,而这个指针,因为swig并未到找它的所对应的class,所以php中无法直接用它。

无论如何,返回指针是行不通了。于是想到另一种方法,在c++中继承ResultSet然后return 这个class。.i文件如下:

%module Td
%{
#include "Td.h"
%}
class Td : public ResultSet
public:

..............................

};

问题又来了,ResultSet是抽象类,它的函数都是纯虚函数,必须要完全实现一遍,可我怎么知道它是怎么实现的?在哪里实现的?当然要用ResultSet的,但是问题是不实现这些虚函数,Td这个class根本无法实例化,更别提return了。

还冒出一个愚蠢的想法,就是直接返回ResultSet,可cpp文件就直接报错:纯虚函数,不能实例化,是的,return &rs;是愚蠢的。

最后,忽然才明白自己一直掉入了怪圈,分明是很简单的事嘛!

%module Td
%{
#include "Td.h"
%}
class Td
public:

ResultSet *rs;

public:

char* getString(char* column);

char* getString(Int columnindex);

...................................

};

这样不就行了吗?这个Td中的所有函数,与ResultSet一样,但是它们的实现,就用rs->xxx来实现,这不就行了吗?

Resultset中函数还真不少,copy/paste就用了半天,反正都是力气活,倒也还好。只不过其中还有一些问题,如,php不支持overload,所以类似于getString这样的函数必须用swig提供的rename指令将其中一条重命名,否则,在PHP中使用中,会报“参数类型是模糊的"这样的错误;另外,除了基本的类型,如int char 之外,swig啥也不认识,都会原样将其转为SWIGTYPE_p_xxxx这样的指针,而这样的东西,PHP是不认识的,到时依然没法用,所以,需要将ResultSet中的函数中的其他类型(如int64 size_t sqlstring等等)在.i和.h文件中改写成int char等,这点,对于swig,表示不满意,这些宏定义的东西,应该由它自行转换多好。

不管怎么样,虽然手工的改动烦了点,比起成功的喜悦,还是不算什么的。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

swig扩展php(二) 的相关文章

随机推荐