3

Delphi で使用する Visual Studio で COM オブジェクトを作成しました。

[Guid("9D0CCD2D-75E9-46AC-BC40-C4D84669FC45")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMyComClassDispatch
{
    string PropertyString { get; set; }
    string funcGetString();
    void funcSetString(string aString);
}

[ClassInterface(ClassInterfaceType.None)]
public class MyComClassDispatch : IMyComClassDispatch
{
    public string PropertyString { get; set; }


    public string varString;

    public string funcGetString()
    {
        return varString;
    }

    public void funcSetString(string aString)
    {
        varString = aString;
    }
}

次に、tlb ファイルを生成し、最後に、Delphi 5 にバンドルされている tlibimp.exe を使用して COM オブジェクトに対応するパスカル ファイルを生成しました。

C:\>tlibimp.exe -P+ mylib.tlb

生成されたコードは次のとおりです。

// *********************************************************************//
// DispIntf:  IMyComClassDispatch
// Flags:     (4096) Dispatchable
// GUID:      {9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}
// *********************************************************************//
  IMyComClassDispatch = dispinterface
    ['{9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}']
    property PropertyString: WideString readonly dispid 1610743808;
    function  funcGetString: WideString; dispid 1610743810;
    procedure funcSetString(const aString: WideString); dispid 1610743811;
  end;

問題は、私のプロパティが読み取り専用としてマークされていることです。このツールは C++ コードも生成でき、プロパティを変更できるため、なぜそうなっているのかよくわかりません。

// *********************************************************************//
// Interface   : IMyComClassDispatch
// Indicateurs : (4096) Dispatchable
// GUID        : {9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}
// *********************************************************************//
interface IMyComClassDispatch : public TDispWrapper<IDispatch>
{
  BSTR __fastcall get_PropertyString()
  {
    _TDispID _dispid(/* PropertyString */ DISPID(DISPID_UNKNOWN/*[1610743808]*/));
    TAutoArgs<0> _args;
    OlePropertyGet(_dispid, _args);
    return _args.GetRetVariant();
  }

  void __fastcall set_PropertyString(BSTR Param1/*[in]*/)
  {
    _TDispID _dispid(/* PropertyString */ DISPID(1610743808));
    TAutoArgs<1> _args;
    _args[1] = Param1 /*[VT_BSTR:0]*/;
    OlePropertyPut(_dispid, _args);
  }

  BSTR __fastcall funcGetString()
  {
    _TDispID _dispid(/* funcGetString */ DISPID(DISPID_UNKNOWN/*[1610743810]*/));
    TAutoArgs<0> _args;
    OleFunction(_dispid, _args);
    return _args.GetRetVariant();
  }

  void __fastcall funcSetString(BSTR aString/*[in]*/)
  {
    _TDispID _dispid(/* funcSetString */ DISPID(DISPID_UNKNOWN/*[1610743811]*/));
    TAutoArgs<1> _args;
    _args[1] = aString /*[VT_BSTR:0]*/;
    OleProcedure(_dispid, _args);
  }


  __property   BSTR            PropertyString = {read = get_PropertyString, write = set_PropertyString};
};

これは、COM オブジェクトのプロパティを避ける必要があるということですか、それとも変更する必要があるオプションはありますか? これは tlibimp の問題ですか、それとも COM オブジェクトのプロパティに書き込む命令を生成できないコンパイラの制限ですか?

これについて何か助けていただければ幸いです!

4

2 に答える 2

1

これは、Delphi 5 & 6 tlibimp.exe の既知の不具合です。これを回避するには、Delphi 7 以降のバージョンにアップグレードする必要があります。

于 2012-08-20T15:49:25.960 に答える
0

Tlibimp.exe は Delphi 5 でバグがあり、Borland/CodeGear/Embarcadero からのサポートはありません...

回避策は、生成された pas ファイルの読み取り専用マーカーを削除することです。しかし、コードが正しく呼び出されることを確認するために、動作することを証明するためにいくつかの変更を加えました。

  • COM オブジェクト クラスで、setter 内のファイルに次のように書き込みます。

    public string PropertyString
    {
        get { return varString; }
        set
        {
            varString = value;
            File.WriteAllText(@"C:\Users\elias\Documents\com.txt", varString);
        }
    }
    
  • tlibimp.exe から生成された .pas ファイルのプロパティの読み取り専用マーカーを削除します。

    // *********************************************************************//
    // DispIntf:  IMyComClassDispatch
    // Flags:     (4096) Dispatchable
    // GUID:      {9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}
    // *********************************************************************//
      IMyComClassDispatch = dispinterface
        ['{9D0CCD2D-75E9-46AC-BC40-C4D84669FC45}']
        property PropertyString: WideString dispid 1610743808;
        function  funcGetString: WideString; dispid 1610743810;
        procedure funcSetString(const chaine: WideString); dispid 1610743811;
      end;
    
  • 次に、COM オブジェクトを使用できます。

    var
      MyClass: IMyComClassDispatch;
    begin
      try
        MyClass:= CoMyComClassDispatch.Create;
        MyClass.PropertyString:= 'some value';
      finally
        MyClass._Release;
      end;
    end;
    

そして、ファイルは正しく書き込まれます!

これが私のプロジェクトで遭遇した唯一の問題です。後で他の問題が発生しないことを願っています...

于 2012-08-21T07:49:21.097 に答える