COM对象方法未定义

时间:2015-10-30 13:25:13

标签: php windows delphi com

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

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

这个类包含了100种不同的方法。但是当打电话给他们时:

$com->SomeMethod();

,弹出此错误:

  

致命错误:调用未定义的方法com :: SomeMethod()in   第22行的C:\ xampp \ htdocs \ www \ test.php

当我使用其他COM对象时,这不会发生,例如' InternetExplorer.Application '类。 另外,我知道这个COM对象与Delphi等其他编程语言一样可以正常工作。

我在64位Windows Vista上使用PHP 5.5.19,在32位PHP架构上使用XAMPP。

对于可能发生的事情或者针对这种情况的一些可能的解决方法,我将不胜感激。

修改 COM服务器应用程序是使用Delphi制作的。

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

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

我明白了:

  

致命错误:未捕获的异常&#39;异常&#39;与消息&#39;对象   type com没有创建Iterator&#39;

我想这表明应用程序界面本身可能存在问题,但我不知道该问题可能是什么。我在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(),{ {1}}和FuncName2(),但当我尝试使用FuncName3()调用其中任何一个时,它返回的是此错误:

  

致命错误:调用未定义的方法com :: SomeMethod()in   第22行的C:\ xampp \ htdocs \ www \ test.php

1 个答案:

答案 0 :(得分:1)

COM可能会出现很多问题,但我会尽力帮助。 我知道您使用术语来描述问题,例如调用$ com-&gt; SomeMethod(),但在这种情况下您需要更具体。

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

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

在您的帖子中,您显示IDispatch暴露了三种方法:
 1. FuncName1
 2. FuncName2
 3. FuncName3

因此,您无法在ISrvObject上调用SomeMethod,因为它不是通过IDispatch接口公开的 注意: COM在暴露其界面时使用WideString(UTF-16)文本。在对接口方法进行调用后,请将其考虑在内。