2017-08-29 46 views
-1

我有一個使用Delphi 7構建的32位應用程序,此應用程序使用TChromium(Delphi Chromium Embeded,dcef3-2378分支)來顯示網頁。在這個應用程序中,我使用SOAP服務來檢查ec.europe.eu中的增值稅號碼,並且此應用程序向我提供了Access Viloation。與Delphi7一起使用SOAP時,TChromium/DCEF3會導致「訪問衝突」錯誤

我的項目有三個單位:

Project1.dpr - project. 
VatCheck.pas - automatically build from WSDL 
Unit1.пас - form with button 

的 「AV」 的錯誤是在這條線的 「Unit1.pas」:

outp := WS.checkVat(inp); 

一切都OK,當我評論這行「 Project1.dpr「:

if not CefLoadLibDefault then Exit; 

以下是完整的源代碼。

program Project1; 

uses 
    ceflib, 
    Forms, 
    Unit1 in 'Unit1.pas' {Form1}, 
    VatCheck in 'VatCheck.pas'; 

{$R *.res} 

begin 
    CefSingleProcess := False; 
    if not CefLoadLibDefault then Exit; 
    // 
    Application.Initialize; 
    Application.CreateForm(TForm1, Form1); 
    Application.Run; 
end. 



unit VatCheck; 

interface 

uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; 

const 
    IS_UNQL = $0008; 


type 

    checkVat    = class;     {"urn:ec.europa.eu:taxud:vies:services:checkVat:types"[Cplx] } 
    checkVatResponse  = class;     {"urn:ec.europa.eu:taxud:vies:services:checkVat:types"[Cplx] } 

    // ************************************************************************ // 
    // XML  : checkVat, 
    // Namespace : urn:ec.europa.eu:taxud:vies:services:checkVat:types 
    // ************************************************************************ // 
    checkVat = class(TRemotable) 
    private 
    FcountryCode: WideString; 
    FvatNumber: WideString; 
    published 
    property countryCode: WideString Index (IS_UNQL) read FcountryCode write FcountryCode; 
    property vatNumber: WideString Index (IS_UNQL) read FvatNumber write FvatNumber; 
    end; 



    // ************************************************************************ // 
    // XML  : checkVatResponse, 
    // Namespace : urn:ec.europa.eu:taxud:vies:services:checkVat:types 
    // ************************************************************************ // 
    checkVatResponse = class(TRemotable) 
    private 
    FcountryCode: WideString; 
    FvatNumber: WideString; 
    FrequestDate: TXSDate; 
    Fvalid: Boolean; 
    Fname_: WideString; 
    Faddress: WideString; 
    public 
    destructor Destroy; override; 
    published 
    property countryCode: WideString Index (IS_UNQL) read FcountryCode write FcountryCode; 
    property vatNumber: WideString Index (IS_UNQL) read FvatNumber write FvatNumber; 
    property requestDate: TXSDate  Index (IS_UNQL) read FrequestDate write FrequestDate; 
    property valid:  Boolean  Index (IS_UNQL) read Fvalid write Fvalid; 
    property name_:  WideString Index (IS_UNQL) read Fname_ write Fname_; 
    property address:  WideString Index (IS_UNQL) read Faddress write Faddress; 
    end; 


    checkVatPortType = interface(IInvokable) 
    ['{FF7DB705-D388-D555-FDCA-58B0F7D33A5F}'] 

    // Cannot unwrap: 
    //  - The input part is not a complex type 
    //  - The output part is not a complex type 
    function checkVat(const parameters: checkVat): checkVatResponse; stdcall; 
    end; 

function GetcheckVatPortType(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): checkVatPortType; 


implementation 
uses SysUtils; 

function GetcheckVatPortType(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): checkVatPortType; 
const 
    defWSDL = 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl'; 
    defURL = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService'; 
    defSvc = 'checkVatService'; 
    defPrt = 'checkVatPort'; 
var 
    RIO: THTTPRIO; 
begin 
    Result := nil; 
    if (Addr = '') then 
    begin 
    if UseWSDL then 
     Addr := defWSDL 
    else 
     Addr := defURL; 
    end; 
    if HTTPRIO = nil then 
    RIO := THTTPRIO.Create(nil) 
    else 
    RIO := HTTPRIO; 
    try 
    Result := (RIO as checkVatPortType); 
    if UseWSDL then 
    begin 
     RIO.WSDLLocation := Addr; 
     RIO.Service := defSvc; 
     RIO.Port := defPrt; 
    end else 
     RIO.URL := Addr; 
    finally 
    if (Result = nil) and (HTTPRIO = nil) then 
     RIO.Free; 
    end; 
end; 


destructor checkVatResponse.Destroy; 
begin 
    FreeAndNil(FrequestDate); 
    inherited Destroy; 
end; 

initialization 
    InvRegistry.RegisterInterface(TypeInfo(checkVatPortType), 'urn:ec.europa.eu:taxud:vies:services:checkVat', 'UTF-8'); 
    InvRegistry.RegisterDefaultSOAPAction(TypeInfo(checkVatPortType), ''); 
    InvRegistry.RegisterInvokeOptions(TypeInfo(checkVatPortType), ioDocument); 
    InvRegistry.RegisterInvokeOptions(TypeInfo(checkVatPortType), ioLiteral); 
    InvRegistry.RegisterExternalParamName(TypeInfo(checkVatPortType), 'checkVat', 'parameters1', 'parameters'); 
    RemClassRegistry.RegisterXSClass(checkVat, 'urn:ec.europa.eu:taxud:vies:services:checkVat:types', 'checkVat'); 
    RemClassRegistry.RegisterXSClass(checkVatResponse, 'urn:ec.europa.eu:taxud:vies:services:checkVat:types', 'checkVatResponse'); 
    RemClassRegistry.RegisterExternalPropName(TypeInfo(checkVatResponse), 'name_', 'name'); 

end. 


unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    Label1: TLabel; 
    editCountry: TEdit; 
    Label2: TLabel; 
    editVAT: TEdit; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 
uses VatCheck, XSBuiltIns; 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    WS: checkVatPortType; 
    inp: checkVat; 
    outp: checkVatResponse; 
begin 
    WS := GetcheckVatPortType; 
    inp := checkVat.Create; 
    try 
     inp.countryCode := editCountry.Text; 
     inp.vatNumber := editVAT.Text; 
     try 
     outp := WS.checkVat(inp); 
     except 
     on E: Exception do begin 
      ShowMessage('Error: ' + E.Message); 
      Exit; 
     end{on}; 
     end{try}; 
     if outp.valid then ShowMessage(outp.name_ + #13#10 + outp.address) 
     else ShowMessage(outp.countryCode + outp.vatNumber + ' is invalid VAT number.') 
    finally 
     inp.Free; 
     outp.Free 
    end; 
end; 

end. 

在此先感謝!

+0

這個問題有點寬泛。請提供不工作的部分的代碼示例。 – Andy

回答

0

感謝Chris Thornton's answer,我找到了解決問題的辦法。

問題是,Delphi 7不能識別DEP,而基於RIO的組件爲可執行代碼分配內存而不將其標記爲可執行文件以保持DEP快樂。

Chris還提供瞭解決方案:使用Delphi 2007的SOAP庫重新編譯代碼。