简体   繁体   English

Delphi 7中不兼容的类型

[英]incompatible types in Delphi 7

I have done this as described below: 我已经按照以下说明进行了操作:

uses CDO_TLB, ADODB_TLB; 使用CDO_TLB,ADODB_TLB; _Stream defined in ADODB_TLB unit (Active Data Objects). 在ADODB_TLB单元(活动数据对象)中定义的_Stream。 IMessage, > I Configurationin in CDO_TLB unit (Collaboration Data Objects). IMessage,> I Configurationin位于CDO_TLB单元(协作数据对象)中。 If not already created use the Import Type Library as follows and create: CDO_TLB = C:\\WINDOWS\\system32\\cdosys.dll 如果尚未创建,请按如下所示使用导入类型库并创建:CDO_TLB = C:\\ WINDOWS \\ system32 \\ cdosys.dll
ADO_TLB = C:\\Program Files\\Common Files\\System\\ado\\msadoxx.dll - xx version number ADO_TLB = C:\\ Program Files \\ Common Files \\ System \\ ado \\ msadoxx.dll-xx版本号

Now I get following error: 现在我得到以下错误:

    [Fehler] Unit1.pas(1650): Inkompatible Typen: 'ADODB_TLB.TStream' und 'Classes.TStream'
    [Fehler] Unit1.pas(1651): Inkompatible Typen: 'ADODB_TLB.TStream' und  'Classes.TStream'
    [Fehler] Unit1.pas(1655): Inkompatible Typen: 'Classes.TStream' und 'ADODB_TLB.TStream'
    [Fehler] Unit1.pas(1656): Inkompatible Typen: 'Classes.TStream' und 'ADODB_TLB.TStream'
    [Fehler] Unit1.pas(1720): Inkompatible Typen: 'ADODB_TLB.TStream' und 'Classes.TStream'
    [Fehler] Unit1.pas(1724): Inkompatible Typen: 'Classes.TStream' und 'ADODB_TLB.TStream'

At this statement: 在此声明中:

    SpecStream := MyQuery9.CreateBlobStream(MyQuery9.FieldByName('SpecSheet'), bmRead);
    SaftyStream := MyQuery9.CreateBlobStream(MyQuery9.FieldByName('SaftySheet'), bmRead);

I know that I have change the Type library by importing the TLBs. 我知道我已经通过导入TLB更改了类型库。 But How can I still use both Classes? 但是,如何仍可以同时使用两个类?

Here is my code, that part that is necessary only: (The lines commended out with //we makes an error.) 这是我的代码,仅此部分是必需的:(用//我们推荐的行会出错。)

    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, Grids, DBGrids, ExtCtrls, DBCtrls, MemDS, DBAccess,
      MyAccess, MyDacVcl, StdCtrls, frxClass, frxDesgn, frxDBSet, frxExportPDF,
      jpeg, ComCtrls, SBCookieMgr, SBSimpleSSL, SBHTTPSClient, SBConstants,
      SBHTTPCRL, SBHTTPOCSPClient, SBHTTPCertRetriever,  SBX509,
      SBSSLClient, SBTypes, SBUtils, SBCustomCertStorage, SBCertValidator,
      OleCtrls, SHDocVw ,Wininet, PDFSplitMerge_TLB,
      ActiveX, // IMalloc
      ShlObj, SBArcBase, SBArcZip, // CSIDL_-Konstanten
      ShellAPI; // SHGetSpecialFolderLocation() und SHGetPathFromIDList()


    type
      ...

    implementation

    {$R *.dfm}

    uses  RegExpr, CDO_TLB, ADODB_TLB;

    ..

    procedure TForm1.Button7Click(Sender: TObject);
    var
      oldTabSheet: TTAbSheet;
      SpecStream, SaftyStream: TStream;

      MyAN: string;
      MyLief: String;

    begin
      oldTabSheet := pageControl1.ActivePage;
      pageControl1.ActivePage:= TabSheet5;
      //WebBrowser1.Navigate(PrgDirName+'\laborbedarf.pdf');
      //WebBrowser1.Quit;
      //Radiobutton1.Checked:=NOT(radiobutton1.Checked);
      //Radiobutton2.Checked:=NOT(radiobutton2.Checked);

        MyAN := MyQuery1.FieldByName('ArtikelNummer').AsString;
        MyLIEF := MyQuery1.FieldByName('Lieferant').AsString;
        if NOT((MyAN = NULL) or (MyAN = ''))  then
          begin
          (* ---------------------------------------------------------- LIEFERANT 1 ---*)

          if MyLIEF = DBGrid1.Columns[11].PickList[0] then
            begin
            MyQuery9.SQL.Text:='select * from stoff WHERE   RecID = :Old_RecID';
            MyQuery9.ParamByName('Old_RecID').AsInteger := MyQuery1.FieldByName('RecID').AsInteger;
            MyQuery9.Execute;
    //we        SpecStream := MyQuery9.CreateBlobStream(MyQuery9.FieldByName('SpecSheet'), bmRead);
    //we        SaftyStream := MyQuery9.CreateBlobStream(MyQuery9.FieldByName('SaftySheet'), bmRead);
            MyStream2S := TMemoryStream.Create;
            MyStream3S := TMemoryStream.Create;
            MyStream2S.Clear; MyStream3S.clear;
    //we        MyStream2S.LoadFromStream(SaftyStream );
    //we        MyStream3S.LoadFromStream(SpecStream );

            if RadioButton1.Checked then
              begin
                try

                  DeleteFile(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  MyStream2S.SaveToFile(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  WebBrowser1.Navigate(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  Radiobutton1.Checked:= false;
                  Radiobutton2.Checked:= true;

                except
                  end;

                try
                  DeleteFile(GetTempDirectory+'Spezifikation_tmp.pdf');
                  MyStream3S.SaveToFile(GetTempDirectory+'Spezifikation_tmp.pdf');
                  WebBrowser1.Navigate(GetTempDirectory+'Spezifikation_tmp.pdf');
                  Radiobutton1.Checked:= true;
                  Radiobutton2.Checked:= false;


                except
                  end;

              end
            else if RadioButton2.Checked then
              begin
                try

                  DeleteFile(GetTempDirectory+'Spezifikation_tmp.pdf');
                  MyStream3S.SaveToFile(GetTempDirectory+'Spezifikation_tmp.pdf');
                  WebBrowser1.Navigate(GetTempDirectory+'Spezifikation_tmp.pdf');
                  Radiobutton1.Checked:= true;
                  Radiobutton2.Checked:= false;

                except
                  end;

                try

                  DeleteFile(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  MyStream2S.SaveToFile(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  WebBrowser1.Navigate(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  Radiobutton1.Checked:= false;
                  Radiobutton2.Checked:= true;

                except
                  end;

              end;


            end
            (* ---------------------------------------------------------- LIEFERANT 2 ---*)
          else
            if MyLIEF = DBGrid1.Columns[11].PickList[1] then

            begin
            MyQuery9.SQL.Text:='select * from stoff WHERE   RecID = :Old_RecID';
            MyQuery9.ParamByName('Old_RecID').AsInteger := MyQuery1.FieldByName('RecID').AsInteger;
            MyQuery9.Execute;
            //SpecStream := MyQuery9.CreateBlobStream(MyQuery9.FieldByName('SpecSheet'), bmRead);
    //we        SaftyStream := MyQuery9.CreateBlobStream(MyQuery9.FieldByName('SaftySheet'), bmRead);
            MyStream2S := TMemoryStream.Create;
            MyStream3S := TMemoryStream.Create;
            MyStream2S.Clear; MyStream3S.clear;
    //we        MyStream2S.LoadFromStream(SaftyStream );
            //MyStream3S.LoadFromStream(SpecStream );

           Radiobutton1.Checked:= false;
           Radiobutton2.Checked:= true;

            if RadioButton2.Checked then
              begin
                try

                  DeleteFile(GetTempDirectory+'Spezifikation_tmp.pdf');
                  MyStream3S.SaveToFile(GetTempDirectory+'Spezifikation_tmp.pdf');
                  if Filesize(GetTempDirectory+'Spezifikation_tmp.pdf') > 5 then
                    WebBrowser1.Navigate(GetTempDirectory+'Spezifikation_tmp.pdf')
                  else
                    WebBrowser1.Navigate(PrgDirName+'\PDFLeer.pdf');

                  Radiobutton1.Checked:= true;
                  Radiobutton2.Checked:= false;

                except
                  ShowMessage(' Kann PDF nicht anzeigen, wurde es nicht geladen weil nicht verfügbar?');
                  end;

                try

                  DeleteFile(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  MyStream2S.SaveToFile(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf');
                  if Filesize(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf') > 5 then
                    WebBrowser1.Navigate(GetTempDirectory+'Sicherheitsdatenblatt_tmp.pdf')
                  else
                    WebBrowser1.Navigate(PrgDirName+'\PDFLeer.pdf');

                  Radiobutton1.Checked:= false;
                  Radiobutton2.Checked:= true;

                except
                  ShowMessage(' Kann PDF nicht anzeigen, wurde es nicht geladen weil nicht verfügbar?');

                  end;

              end;


            end   ;

        //MyQuery1.Next;
        MyStream3S.Clear;
        MyStream2S.Clear;
        MyStream3S.free;
        MyStream2S.free;

        end
      else
        begin
        ShowMessage('Kein PDF in DB gefunden!');
        end;




    end;

Obviously you have second declaration of TStream in ADODB_TLB unit, and when you use both ADODB_TLB and Classes in same unit - TStream will be used from last unit it is declared. 显然,您在ADODB_TLB单元中有第二个TStream声明,并且当您在同一单元中同时使用ADODB_TLBClassesTStream将在最后一个单元中使用。 You can resolve this: 您可以解决此问题:

  1. By using TStream from desired unit explicitly. 通过显式使用所需单元中的TStream

    var
    S1: ADODB_TLB.TStream;
    S2: Classes.TStream;

  2. By renaming one TStream to something more unique like ADODB_TLB.TStream to ADODB_TLB.TADOStream . 通过将一个TStream重命名为更独特的东西,例如ADODB_TLB.TStreamADODB_TLB.TADOStream I would prefer this way. 我希望这样。 You can do this by reimporting ADODB_TLB and specify type renaming for TStream (this is selected in import wizard) 您可以通过重新导入ADODB_TLB并为TStream指定类型重命名来TStreamTStream (在导入向导中选择该名称)

The problem is your interface uses Classes which defines TStream . 问题是您的接口使用定义TStream Classes
And your implementation uses ADODB_TLB which also defines TStream . 而且您的实现使用ADODB_TLB ,它也定义了TStream
NOTE : As Sertac points out, you would also get errors if you included both units in the interface section, but had ADODB_TLB after Classes . :由于Sertac所指出的,你也会,如果你包括在接口部分两个单元,但必须得到错误ADODB_TLB 之后 Classes

So whenever you use TStream in the interface section of your unit, you're using Classes.TStream . 因此,每当在单元的接口部分中使用TStream时,就在使用Classes.TStream But in the implementation section, that would be ADODB_TLB.TStream , which is why you're getting the errors. 但是在实现部分中,它将是ADODB_TLB.TStream ,这就是为什么出现错误的原因。 The errors also occur when you call a routine in another unit that uses a different type of TStream (such as CreateBlobStream which returns Classes.TStream ). 当在使用不同类型的另一单元调用一个例程的错误也发生TStream (如CreateBlobStream返回Classes.TStream )。

//You declared SaftyStream in the implementation section, so it is ADODB_TLB.TStream.
//But CreateBlobStream returns a Classes.TStream.
//So they are incompatible.
SaftyStream := MyQuery9.CreateBlobStream(MyQuery9.FieldByName('SaftySheet'), bmRead);

//You don't show where you declare MyStream2S.
//I assume interface section, so it is Classes.TStream.
//Classes.TStream.LoadFromStream expects to be given a Classes.TStream
//But SaftyStream is ADODB_TLB.TStream, which is incompatible.
MyStream2S.LoadFromStream(SaftyStream );

The first thing you need to decide in resolving this is which of the two TStream s you actually want to use? 解决此问题时,您需要决定的第一件事是您实际要使用两个TStream的哪个? (I suspect the one in Classes . As Sertac points out, CreateBlobStream returns a Classes.TStream , so you should use that one.) (我怀疑一个中Classes 。作为Sertac指出, CreateBlobStream返回Classes.TStream ,所以你应该使用那一个。)

Options 选件

  • First consider whether you really need to use ADODB_TLB? 首先考虑您是否真的需要使用ADODB_TLB? Delphi already has wrappers for this type library in ADODB.pas . Delphi在ADODB.pas已经为该类型库提供了ADODB.pas If you can use it, you would be following "more traditional" Delphi paradigms. 如果可以使用它,您将遵循“更传统的” Delphi范例。

  • If you must code against ADO directly, then I suggest you move the uses ADODB_TLB into the interface section, and before uses Classes . 如果您必须直接针对ADO进行编码,那么建议您将uses ADODB_TLB移到接口部分中,然后 uses Classes This way the most recent definition of TStream (from Classes ) would apply to your whole unit. 这样, TStream最新定义(来自Classes )将适用于您的整个单元。

  • You can also reference the types with a fully qualified name as in point 1 of VitaliyG's answer . 您也可以使用VitaliyG答案的第 1点中的完全限定名称来引用类型。 Ie Classes.TStream Classes.TStream

  • However, in this case I wouldn't advise renaming TStream as in point 2 of his answer. 但是,在这种情况下,我不建议像他回答的第2点那样重命名TStream The reason is that these are units shipped with Delphi, and other units have dependencies on them. 原因是这些是Delphi附带的单元,其他单元对此也有依赖性。 But if the naming conflict were in your own units, then I would definitely suggest choosing more specific names to differentiate the types. 但是,如果命名冲突在您自己的单位内,那么我绝对会建议选择更具体的名称来区分类型。 And if the types are truly the same thing, then maybe you should rather merge them into a shared third unit. 如果类型确实是同一回事,那么也许您应该将它们合并为一个共享的第三单元。


ADDENDUM 附录

You mentioned in a comment: 您在评论中提到:

I want to integrate this procedure: Create *. 我要集成此过程: 创建*。 Mht-file (Web Archive) It worked fine before I added the ADODB_TLB in the uses clause. Mht-file(Web存档)在我在uses子句中添加ADODB_TLB之前,它运行良好。

This explains why you added the unit. 这说明了为什么要添加单位。 However, given the naming conflict, and potential for unnecessary headaches: I suggest you rather isolate the functionality into a small dedicated unit (eg MHTBuilder.pas ). 但是,考虑到命名冲突和潜在的不必要麻烦:我建议您宁可将功能隔离到一个小的专用单元中(例如MHTBuilder.pas )。

  • Then your unit won't need to use ADODB_TLB (it will be used by MHTBuilder). 然后,您的单元将不需要使用ADODB_TLB (它将由MHTBuilder使用)。
  • Your unit will use MHTBuilder instead. 您的单位将改用MHTBuilder
  • And call a simple function to build the MHT file. 并调用一个简单的函数来构建MHT文件。

This is closely related to my comment about you needing to split your code into smaller functions. 这与我关于您需要将代码拆分为较小功能的评论密切相关。 Breaking things down into smaller pieces makes it much easier to manage complexity. 将事情分解成更小的部分,可以更轻松地管理复杂性。 Basically you should avoid trying to lump all your functionality and options into a huge method (as you did). 基本上,您应该避免尝试将所有功能和选项都整合到一个巨大的方法中(就像您所做的那样)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM