【发布时间】:2016-01-30 22:40:38
【问题描述】:
我在 php 中调用 COM 类中的任何方法时遇到问题。为了找到该类中的所有方法,我使用了:
$com = new COM('Some.Class.Name');
com_print_typeinfo($com);
这个类包含大约 100 种不同的方法。但是当调用它们中的任何一个时:
$com->SomeMethod();
,弹出这个错误:
致命错误:调用未定义的方法 com::SomeMethod() C:\xampp\htdocs\www\test.php 第 22 行
当我使用其他 COM 对象时不会发生这种情况,例如 'InternetExplorer.Application' 类。 另外,我知道这个 COM 对象可以与 Delphi 等其他编程语言一起正常工作。
我在 64 位 Windows Vista 和 XAMPP 上使用 PHP 5.5.19,以及 32 位 PHP 架构。
对于可能发生的事情或解决这种情况的一些可能的解决方法,我将不胜感激。
编辑: COM 服务器应用程序是用 Delphi 制作的。
这可能是另一个线索:当我使用代码时
$com = new COM('Some.Class.Name');
foreach ($com as $obj) {
echo $obj->Name . "<br />";
}
我明白了:
致命错误:未捕获的异常 'Exception' 带有消息 'Object of type com 没有创建 Iterator'
我猜这表明应用程序界面本身可能存在问题,但我不知道问题可能是什么。我在 PHP 中工作,所以 COM 对象的内部对我来说完全是模糊的。但我非常感谢有关解决这种情况的具体步骤的任何线索。
EDIT2: 这是 Srv_TLB.pas 文件中的简而言之代码。
unit Srv_TLB;
{$TYPEDADDRESS OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface
uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
const
// TypeLibrary Major and minor versions
SrvMajorVersion = 1;
SrvMinorVersion = 0;
LIBID_Srv: TGUID = '{xxxxx-xxx-xxx-xx...}';
IID_ISrvObject: TGUID = '{yyyyy-yyy-yyy-yy..}';
CLASS_SrvObject: TGUID = '{zzzzz-zzz-zzz-z...}';
type
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
ISrvObject = interface;
ISrvObjectDisp = dispinterface;
// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
SrvObject = ISrvObject;
ISrvObject = interface(IDispatch)
['{yyyyy-yyy-yyy-yy..}']
function FuncName1(const param1: WideString; const param2: WideString): Integer; safecall;
function FuncName2: OleVariant; safecall;
function FuncName3(const param: WideString): Integer; safecall;
end;
// *********************************************************************//
// DispIntf: ISrvObjectDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {yyyyy-yyy-yyy-yy..}
// *********************************************************************//
ISrvObjectDisp = dispinterface
['{yyyyy-yyy-yyy-yy..}']
function FuncName1(const param1: WideString; const param2: WideString): Integer; dispid 3;
function FuncName2: OleVariant; dispid 4;
function FuncName3(const param: WideString): Integer; dispid 5;
end;
CoSrvObject = class
class function Create: ISrvObject;
class function CreateRemote(const MachineName: string): ISrvObject;
end;
implementation
uses ComObj;
class function CoSrvObject.Create: ISrvObject;
begin
Result := CreateComObject(CLASS_SrvObject) as ISrvObject;
end;
class function CoSrvObject.CreateRemote(const MachineName: string): ISrvObject;
begin
Result := CreateRemoteComObject(MachineName, CLASS_SrvObject) as ISrvObject;
end;
end.
问题是(从 PHP 方面):
我可以使用$com = new COM('The.Class.Name'); 或$com = new COM('{GUID}'); 初始化COM 对象,并使用com_print_typeinfo($com); 获取类型信息,因此我可以看到该对象应该具有FuncName1()、FuncName2() 和FuncName3() 方法,但是当我尝试用$com->FuncName1(param1, param2); 调用它们中的任何一个时,它返回的是这个错误:
致命错误:调用未定义的方法 com::SomeMethod() C:\xampp\htdocs\www\test.php 第 22 行
【问题讨论】:
-
在系统上正确注册了吗?我会看看如何找到 DLL 并使用
regsvr32 nameof.dll注册它,或者如果它是进程外 EXE,则使用nameof.exe /regserver运行 EXE -
@MichaelPetch 谢谢。是的,它是一个.exe。我按照你的建议做了。还是一样。
-
忘了说我的系统是x64的,.exe文件是为x32编译的,不知道这是否有区别。
-
您使用的是 64 位版本的 PHP 还是 32 位版本的 PHP?
-
phpinfo() : 架构 x86