在php中调用其它编程语言的接口,个人感觉最方便的就是使用COM组件了。最近小弟刚开始接触php,在研究调用c++编写的COM组件的时候遇到了“'Failed to create COM object”这个错误,费了不少功夫终于解决。
高版本的php需要手动开启支持COM,基本就是在php.ini中修改配置为com.allow_dcom = true和extension=php_com_dotnet.dll。如果是这种错误很好解决。其实这种配置错误我觉得一般很少有人会犯,还有不少人说可以通过加载测试wps或者word组件的方式来测试COM组件支持是否正常,但是由于权限的问题,这种测试方式不太好用。后来我在http://php.net/manual/zh/class.com.php文档说明中找到$db = new COM("ADODB.Connection",NULL, 65001 );经测试加载正常,说明一定是我写的COM组件有问题,结果确实如此。
之前网上有不少php加载c++编写的COM组件的例子,可能是php版本太低的原因,那种创建组件的方式已经不合适了,如果使用的是php5.2之前的版本可能无误。我使用的是php5.5,被误导了。
我的php版本是5.5.12,使用vs2013编写COM组件,下面是过程:
1,启动栏找到vs2013,右键管理员权限打开,只所以用管理员身份打开是因为待会注册COM组件的时候方便。在c++中新建ATL项目,
2,点击完成,在工程上右键添加类,选择ATL COM+10。
3,工程右键点击添加类。下面是最关键的地方,右下角的ProgID一定要手动添加,格式为"项目名称.简称",项目名称就是生成dll的名字,待会再php里面加载的时候也要这么写,第二项是简称,不是类名。如果这个地方写错,虽然组件能够注册成功,但是在php中是不识别的。
4,在Itest上添加方法,这个我就不详细写了,我添加了一个add,如下
STDMETHODIMP Ctest::add(LONG a, LONG b, LONG* c)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加实现代码
*c = a + b;
return S_OK;
}
5,然后是编译并且自动注册成组件,重启apache服务。php脚本中如下调用:
<?php
$conn = new COM("ATLProject3.test") or die("Cannot start ADO");
$com = 2;
$conn->add(10, 2, $com);
echo $com;
?>
注意是”组件名.简称“的格式才正确。网上示例中是”组件名.类名“,可能是版本问题,反正我那样调用是失败的。
6,浏览器输入自己php工程目录,显示加载COM组件正常,成功使用COM组件使10加2输出为12.