troubleshooting Question

Delphi, COM and Access Violation calling object methods from an interface instance

Avatar of akede2001
akede2001 asked on
Delphi
16 Comments1 Solution918 ViewsLast Modified:
Windows Vista Ultimate, 64bit, IE 7, Borland Developer Studio 2006


Ran into an interesting problem. I'm not sure what this falls under,
but I did some researching already and can't find anything that seems
to fix the problem.

I've got a class defined as:

  TDynamicNS = class(TComObject, IInternetProtocol)
    function Start(szUrl: PWideChar; OIProtSink:
IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI,
dwReserved: DWORD): HResult; stdcall;
    function Continue(const ProtocolData: TProtocolData): HResult;
stdcall;
    function Abort(hrReason: HResult; dwOptions: DWORD): HResult;
stdcall;
    function Terminate(dwOptions: DWORD): HResult; stdcall;
    function Suspend: HResult; stdcall;
    function Resume: HResult; stdcall;
    function Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HResult;
stdcall;
    function Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD; out
libNewPosition: ULARGE_INTEGER): HResult; stdcall;
    function LockRequest(dwOptions: DWORD): HResult; stdcall;
    function UnlockRequest: HResult; stdcall;
  end;

In the events Start(), Read(), and Terminate(), I have code that is
checking a global record in another unit for an assigned callback.
When I do this, I get an access violation. I'm not sure I'd need to do
any sort of marshalling, as I'm not passing the interface, referencing
it, or doing anything with it. Here's an example of what's going on:

type
  TOnRead = procedure(const AEvent: Integer);

  TGlobalData = record
    OnRead: TOnRead;
  end;

var
  gGlobalData: TGlobalData;

function TDynamicNS.Read(pv: Pointer; cb: ULONG; out cbRead: ULONG):
HResult; stdcall;
begin
  if (Assigned(gGlobalData.OnRead)) then
    gGlobalData.OnRead(0);
end;

The gGlobalData.OnRead event is assigned by another class:
  TMyClass = class(TObject)
  private
    FLastEvent: Integer;
  public
    procedure OnRead(const AEvent: Integer);
  end;

procedure TMyClass.OnRead(const AEvent: Integer);
begin
  FLastEvent := AEvent; //<-- AV here
end;

I know the AV is related to calling the class from the interface.. but
I'm not sure why, or how to fix it. Anyone have any tips? I have
experience in marshalling, but I've never done it with something that
has been defined to classes like this.
ASKER CERTIFIED SOLUTION
developmentguru
President

Our community of experts have been thoroughly vetted for their expertise and industry experience.

Join our community to see this answer!
Unlock 1 Answer and 16 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 16 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros