Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Database/DataSnap    [ Add a report in this area ]  
Report #:  78752   Status: Open
Encounter "Invalid Pointer Operation" when access DataSnap service via in-process
Project:  Delphi Build #:  14.0.3513.24210
Version:    14.0 Submitted By:   Chee Yang Chau
Report Type:  Basic functionality failure Date Reported:  10/18/2009 8:33:58 AM
Severity:    Commonly encountered problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   277617
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
To create a in-process DataSnap application, we may assign TSQLConnection.Driver to the name of a local TDSServer instance.  However, we will encounter "invalid pointer operation" exception.

One of the cause of the problem has filed in QC#78666 (Title: Mismatched in datapacket with DSUtil.StreamToDataPacket)

In addition to the reported QC#78666, there is another problem.  An in-process DataSnap create an instance of TDSServerCommand.  A method of TDSServerCommand create TDBXNoOpRow instance:

function TDSServerCommand.CreateParameterRow: TDBXRow;
  Result := TDBXNoOpRow.Create(FDbxContext);

Most of the methods in TDBXNoOpRow is not implemented.  There are 2 methods in class TDBXNoOpRow, GetStream and SetStream are used in subsequence operations.  This is the reason that cause the exception.

After fix TDBXNoOpRow problem, the data packet will transport to ClientDataSet successfully.  However, you may encounter another "invalid pointer operation" expcetion.  The problem is due to the following 2 methods:

1. procedure TDBXStreamValue.SetValue
2. function TDBXLookAheadStreamReader.ConvertToMemoryStream: TStream;

TDBXLookAheadStreamReader.ConvertToMemoryStream return a managed FStream object to TDBXStreamValue.SetValue.  This stream object become another managed object of TDBXStreamValue.  It turns out that a Stream object managed by two objects and the exception raised when these 2 objects attempt to free the Stream object.

procedure TDBXStreamValue.SetValue(const Value: TDBXValue);
  if Value.IsNull then
    SetStream(Value.GetStream(False), True);

function TDBXLookAheadStreamReader.ConvertToMemoryStream: TStream;
  if FStream = nil then
    Result := nil
    Count := Size;
    if not (FStream is TMemoryStream) then
      StreamTemp := FStream;
      FStream := Stream;
    FStream.Seek(0, soFromBeginning);
    FHasLookAheadByte := false;

    Result := FStream;

Steps to Reproduce:
1. Attempt to fix QC#78666 by modify the DBX source code.

2. Run the following code:

var Q: TSQLConnection;
    D: TDSServer;
    C: TDSServerClass;
    P: TServerProvider;
    N: TDSProviderConnection;
  P := TServerProvider.Create(nil);
  D := TDSServer.Create(nil);
  C := TDSServerClass.Create(nil);
  Q := TSQLConnection.Create(nil);
  N := TDSProviderConnection.Create(nil);
    C.Server := D;
    C.OnGetClass := OnGetClass;


    Q.DriverName := 'DSServer';
    Q.LoginPrompt := False;

    N.SQLConnection := Q;
    N.ServerClassName := 'TServerProvider';
    N.Connected := True;

    ClientDataSet1.RemoteServer := N;
    ClientDataSet1.ProviderName := 'DataSetProvider1';


3. You may also run a demo project from attachment.
Refer to

Markus Humm at 11/18/2009 4:09:37 AM -
Marked as "needs attention"

Server Response from: ETNACODE01