COM对象方法未定义


COM object method undefined

我在php中调用COM类内的任何方法时都遇到了问题。为了找到该类中的所有方法,我使用了:

$com = new COM('Some.Class.Name');
com_print_typeinfo($com);

这个类包含大约100种不同的方法。但当打电话给他们中的任何一个时:

$com->SomeMethod();

,弹出此错误:

致命错误:调用中未定义的方法com::SomeMethod()C: ''axamp''htdocs''www''test.php,位于第22行

当我使用其他COM对象时,不会发生这种情况,如"InternetExplorer.Application"类。此外,我知道这个COM对象可以像预期的那样与Delphi等其他编程语言配合使用。

我使用的是64位WindowsVista上的PHP5.5.19和32位PHP架构的XAMPP。

我将感谢任何关于可能发生的事情的线索或解决这种情况的可能方法。

编辑:COM服务器应用程序是用Delphi制作的

这可能是另一条线索:当我使用代码时

$com = new COM('Some.Class.Name');
foreach ($com as $obj) { 
    echo $obj->Name . "<br />"; 
} 

我得到:

致命错误:未捕获异常"exception",消息为"Object of"type com没有创建Iterator的

我想这表明应用程序接口本身可能有问题,但我不知道这个问题可能是什么。我用PHP工作,所以COM对象的内部对我来说完全是模糊的。但我非常感谢任何关于解决这种情况的具体步骤的线索。

第2版:这是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: ''axamp''htdocs''www''test.php,位于第22行

COM可能会出现很多问题,但我会尽我所能提供帮助。我知道你会用一些术语来描述这个问题,比如调用$com->SomeMethod(),但在这种情况下你需要更具体。

COM通过两个基本接口IUnknown和IDispatch公开其类和功能
它还有一个C类型的DLL结构,用于向"外部"世界公开函数(而不是方法或类)
可以直接链接到DLL的语言,通过读取导出表(如Delphi),直接在COM公开的接口上进行调用(使用IUnknown接口)。

脚本语言(如javascript、PHP-python等)不能直接在接口上调用。相反,他们使用IDispatch接口
此接口充当代理,通过简单文本公开所有COM功能
IDispatch接口定义了以下各项的标准方法:
1.查询COM公开的接口
2.对象的方法名称
3.每种方法的参数

在您的帖子中,您显示IDispatch公开了三种方法:
1.函数名称1
2.函数名称2
3.函数名称3

因此,不能对ISrvObject调用SomeMethod,因为它不是通过IDispatch接口公开的
注意:COM在公开其接口时使用WideString(UTF-16)文本。一旦对接口方法进行调用,就要考虑到这一点。