TYPE LIBRARY EDITOR的问题

时间:2014-09-18 07:18:26

标签: delphi

多年前我写了一些COM DLL的i Delphi 4(客户端/服务器)。我没有遇到任何问题。后来我升级到Delphi 7(企业版),现在我遇到了问题:

    File-> New -> Other -> ActiveX -> Automation Object -->  No problems.  

    Enter text "TESTPROJ" (CoClass neme) -->  No problems.  

// Multiple Instances - Multiple Instances
// Threading Model:   _ tmAppartment 
// Clickbox:  Generate support Code  -- Unclicked

当我单击OK时,类型库编辑器出现两个LINES i视图部分(ITESTPROJ和TESTPROJ)。这似乎是正确的。

I then click/ mark ITESTPROC. ITESTPROC gets marked.  Then I click NEW METHOD. 

A new Item (below ITESTPROC - named Method1) appears.  

Namebox says METHOD1. ID-box says 201.

但是:

调用Kind-和TYPE-框是灰色的(“禁用”)..

我可以在Invoke kind编辑框中读取“Function”。

问题是:我不能创建任何函数 - 只有这个编辑器的程序。

(我被告知(教导/阅读)我通过设置Invoke类和RETURN类型(在参数中)来创建一个函数,但我根本不能使用Invoke类。

有人可以告诉我为什么吗?如何使用该编辑器创建函数(拼命地需要TLB文件)......

(我已经尝试将返回类型设置为HRESULT,字符串,整数等。这给了我绝对没有 - 只有程序和程序......(带/不带参数)..

1 个答案:

答案 0 :(得分:2)

通过IDispatch接口访问Automation对象中的方法和属性,特别是通过其Invoke()方法。您定义的任何方法都被强制为“函数”的“调用种类”,因为在调用DISPATCH_METHOD时将使用Invoke()标志调用它。这是无法改变的,这就是为什么这个领域是灰色的。默认情况下,“参数”页面上的“返回类型”设置为HRESULT保持这种,请参阅下面的原因。

要定义一个返回值的“函数”,您只需创建一个具有参数的方法,该方法使用指针数据类型并标记为Out和{{1修饰符标志。例如,要创建返回String的函数,请创建一个带有RetVal [out,retval]参数的方法。编辑器将生成如下所示的存根实现:

BSTR*

您所要做的就是返回所需的字符串值,例如:

type
  TTestProj = class(TAutoObject, IConnectionPointContainer, ITestProj)
  ...
  protected
    function Method1: WideString; safecall;
  ...
  end;

function TTestProj.Method1: WideString;
begin

end;

function TTestProj.Method1: WideString; begin Result := 'my value'; end; 调用约定将为您处理剩下的事情。要报告错误,只需引发异常即可。 RTL将调用SetErrorInfo()并向调用者返回适当的safecall

HRESULT

如果您没有提出异常,则来电者会收到function TTestProj.Method1: WideString; begin if some condition then raise Exception.Create('error message'); Result := 'my value'; end; HRESULT

会在实现代码中将该方法视为普通函数,但 CALLER 看到的实际签名是S_OK。这就是为什么你必须将方法的返回类型设置为function Method1(out Result: WideString): HRESULT; stdcall;。 Delphi的HRESULT调用约定在实现方面重新排序,以便于使用。

如果您没有定义具有safecall标志的任何参数,编辑器将创建“过程”而不是“函数”。例如,如果您创建RetVal BSTR *参数,则存根实现将如下所示:

[out]

来电者看到的签名是type TTestProj = class(TAutoObject, IConnectionPointContainer, ITestProj) ... protected procedure Method1(out Param1: WideString); safecall; ... end; procedure TTestProj.Method1(out Param1: WideString); begin end;

或者,如果你只是简单地省略参数,那么存根就会像这样结束:

function Method1(out Param1: WideString): HRESULT; stdcall;

来电者看到的签名是type TTestProj = class(TAutoObject, IConnectionPointContainer, ITestProj) ... protected procedure Method1; safecall; ... end; procedure TTestProj.Method1; begin end;