0

I using Delphi Embedding Chromium (CEF1) on my application and am having trouble reading the cookie data of an URL.

I have found this code (included below), but on XE3 I get an exception when I use it about this line:

if WaitForSingleObject(vis.pEvent.Handle, INFINITE) = WAIT_OBJECT_0 then begin

The exception is

Project guiclient.exe raised exception class EAccessViolation with message 'Access violation at address 00000000'. Read of address 00000000

implying one of the objects is not created or initialised properly.

The code I am using (copied from the above forum link) is:

  TCustomVisitor = class (TCefCookieVisitorOwn)
    private
      fcookie: PCefCookie;
      function visit(const name, value, domain, path: ustring; secure, httponly,
            hasExpires: Boolean; const creation, lastAccess, expires: TDateTime;
            count, total: Integer; out deleteCookie: Boolean): Boolean; override;
    public
      pEvent: TEvent;
      function getCookies: PCefCookie;
      constructor Create; override;
  end;

constructor TCustomVisitor.Create;
begin
  inherited;
  pEvent := TEvent.Create(nil, False, False, 'ev.chromium');
  new(fcookie);
end;

function TCustomVisitor.getCookies;
begin
  Result := fcookie;
end;

function TCustomVisitor.visit(const name, value, domain, path: ustring; secure, httponly,
            hasExpires: Boolean; const creation, lastAccess, expires: TDateTime;
            count, total: Integer; out deleteCookie: Boolean): Boolean;
begin
    fcookie.name := CefString(name);
    fcookie.value := CefString(value);
    fcookie.domain := CefString(domain);
    fcookie.path := CefString(path);
    fcookie.secure := secure;
    fcookie.httponly := httponly;
    fcookie.has_expires := hasExpires;
    //fcookie.creation := DateTimeToCefTime(creation);
    //fcookie.last_access := DateTimeToCefTime(lastAccess);
    //fcookie.expires  := DateTimeToCefTime(expires);

    SetEvent(pEvent.Handle);
end;


procedure TfrmAuth.bt_okClick(Sender: TObject);
var
  vis: TCustomVisitor;
  cname, cvalue: uString;
  ccookie: PCefCookie;
begin
  if crm.Browser<>nil then begin
    vis := TCustomVisitor.Create;
    try
      CefVisitUrlCookies(ed_url.Text, true, vis);

      // !!! This line causes the access violation
      if WaitForSingleObject(vis.pEvent.Handle, INFINITE) = WAIT_OBJECT_0 then begin
        ccookie := vis.getCookies;
        cname := CefString(@ccookie.name);
        cvalue := CefString(@ccookie.value);
      end;
    finally
      vis.Free;
    end;
  end;
end;
David
  • 13,360
  • 7
  • 66
  • 130
Martin
  • 1,065
  • 1
  • 17
  • 36
  • 1
    What is the error you get? Error info is valuable - please post it! Also it's probably worth including your code as you have it, not a link to a forum. It's best to (a) have all information in the question itself, not a link that may die in future; (b) see your actual code in case the cause is an error converting the example code to fit your app. – David Feb 01 '13 at 08:57
  • I don't have report the error because it is not a "human" error, is a hex code (I think). I think there is some problem with the code in the link. – Martin Feb 01 '13 at 09:02
  • Well, what is the hex code? (An ICE, internal compiler error? Or does it compile and is the code a HRESULT? Or... What is it? I don't know, and you haven't said.) *Please include all information!* We can't help you based on guesswork. – David Feb 01 '13 at 09:08
  • This is the error: "Project guiclient.exe raised exception class EAccessViolation with message 'Access violation at address 00000000'. Read of address 00000000". Can this help you? – Martin Feb 01 '13 at 09:34
  • Make sure you're creating an instance of the visitor. In that code it's the line `vis := TCustomVisitor.Create`. – TLama Feb 01 '13 at 09:55
  • The instance of Visitor is created. As you can see on link. – Martin Feb 01 '13 at 10:33
  • I see, so you're using exactly the code from that link. – TLama Feb 01 '13 at 11:41
  • 1
    TLama, I wouldn't be sure of that, he hasn't actually posted his actual code yet. Martin, it's easy to make mistakes when copy/pasting code... *please*, if you want help, you need to [write a better question](http://stackoverflow.com/questions/how-to-ask). I have edited your question to be clearer, but please add your own, real code in, plus any other useful information. – David Feb 01 '13 at 13:53
  • Given the code actually shown so far, something inside of `CefVisitUrlCookies()` (which has not been shown yet) has to be freeing/corrupting the `TCustomVisitor` object in some way. That is the only way that either the `vis` variable or its `pEvent` member could be invalid by the time `WaitForSingleObject()` is called. – Remy Lebeau Feb 01 '13 at 20:32

1 Answers1

1

it's very simple. CefVisitUrlCookies takes you object as reference-counting interface, and releases it upon return and the obejct destroys itself, so you get access violation in attempt to access fried object. To avoid this problem you may want to either store reference to the object among local variables, or call _addref explicitly:

vis._AddRef();
CefVisitUrlCookies(ed_url.Text, true, vis);
WaitForSingleObject(...)
vis._Release();

or

ivis: ICefCookieVisitor;
...
ivis := vis;
CefVisitUrlCookies(ed_url.Text, true, ivis);
WaitForSingleObject(...)
ivis := nil;

and don't forget to remove Free call. You should never explicitly free interfaced objects with reference counting.