Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: During the conversion process, I encountered some problems.Help,thank you



Permlink Replies: 7 - Last Post: Jan 26, 2018 9:08 AM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
huang weifeng

Posts: 8
Registered: 2/24/18
During the conversion process, I encountered some problems.Help,thank you
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 2:41 AM
During the conversion process, I encountered some problems. DELPHI is converted into C++ Builder. Can you help me see what the problem is?
the saveToStream function please view https://forums.embarcadero.com/thread.jspa?threadID=276980&tstart=0
class procedure TADOTools.loadFromStream2(pvDataSet: TCustomADODataSet;
  pvStream: TMemoryStream);
var
   V:OLEVariant;
   AR:_Recordset;
   AStream:_Stream;
   P:Pointer;
begin
   pvStream.Position:=0;
   OLEVariant(pvDataSet.Recordset).Open(TStreamAdapter.Create(pvStream) as IUnknown, adPersistADTG);
 
   AR.Open(AStream, EmptyParam,adOpenUnspecified, adLockUnspecified, -1);
   pvDataSet.Recordset:=ADOInt._Recordset(AR);
 
 
   V:=VarArrayCreate([0,pvStream.Size-1], varByte);
   P:=VarArrayLock(V);
   try
     Move(pvStream.Memory^, P^, pvStream.Size);
   finally
     VarArrayUnLock(V);
   end;
 
   AStream:=CoStream.Create;
   AStream.Open(EmptyParam,adModeUnknown,adOpenStreamUnspecified,'','');
   AStream.Type_:=adTypeBinary;
   AStream.Write(V);
 
   AR:=_Recordset(CoRecordset.Create);
   AStream.Position:=0;
   AR.Open(AStream,EmptyParam,adOpenUnspecified, adLockUnspecified, -1);
   pvDataSet.Recordset:=ADOInt._Recordset(AR);
 
end;

I don't know how to convert this line
TStreamAdapter.Create(pvStream) as IUnknown

Here is part of my code.
void __fastcall loadFromStream(TADODataSet *pvDataSet,TMemoryStream *pvStream)
{
   int bounds[2] = {0, pvStream->Size-1};
   Variant s=VarArrayCreate(bounds,1, varByte);
   pvStream->Position=0;
   void *P=VarArrayLock(s);
   try {
	   Move(pvStream->Memory, P, pvStream->Size);
   }
   __finally {
			VarArrayUnlock(s);
   }
   OleVariant V=s;
   _di__Recordset RS =CoRecordset::Create();
   _di__Stream AStream = CoStream::Create();
   try {
		//pvDataSet->Recordset->Open(pvStream,NULL,-1,-1,-1);
		AStream->Open(EmptyParam,0,-1,"","");
		AStream->Set_Type_(1);
		AStream->Write(V);
		AStream->Position=0;
		//AStream->Size;
	        //pvDataSet->Recordset->Open(OleVariant(AStream), NULL,0, 1, 256);
		RS->Open(OleVariant(AStream),NULL,-1,1,-1);
	        //AStream->Close();
		pvDataSet->Recordset=RS;
   }
   catch (const Exception &)
   {
		throw;
   }
}

The problem may be here.if view the size attribute will be prompted not open.
AStream->Open(EmptyParam,0,-1,L"",L"");
AStream->Set_Type_(1);
AStream->Write(V);
AStream->Position=0;
roca robin

Posts: 140
Registered: 9/10/06
Re: During the conversion process, I encountered some problems.Help,thank you
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 3:08 AM   in response to: huang weifeng in response to: huang weifeng
I don't know how to convert this line
TStreamAdapter.Create(pvStream) as IUnknown

I think in my short experienced using c++builder for a week that can be translated to this:

TStreamAdapter *pvStream = new TStreamAdapter();
huang weifeng

Posts: 8
Registered: 2/24/18
Re: During the conversion process, I encountered some problems.Help,thank you
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 3:38 AM   in response to: roca robin in response to: roca robin
roca robin wrote:
I don't know how to convert this line
TStreamAdapter.Create(pvStream) as IUnknown

I think in my short experienced using c++builder for a week that can be translated to this:

TStreamAdapter *pvStream = new TStreamAdapter();

I tried this kind of writing, but the system prompt error, error message for "Could not find a match for 'TStreamAdapter: : TStreamAdapter ()'"
roca robin

Posts: 140
Registered: 9/10/06
Re: During the conversion process, I encountered some problems.Help,thank you
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 6:55 AM   in response to: huang weifeng in response to: huang weifeng
huang weifeng wrote:
roca robin wrote:
I don't know how to convert this line
TStreamAdapter.Create(pvStream) as IUnknown

I think in my short experienced using c++builder for a week that can be translated to this:

TStreamAdapter *pvStream = new TStreamAdapter();

I tried this kind of writing, but the system prompt error, error message for "Could not find a match for 'TStreamAdapter: : TStreamAdapter ()'"

I think this will workout,,
TMemoryStream *MStream = new TMemoryStream();
TStreamAdapter *pvStream = new TStreamAdapter(MStream, soReference);
huang weifeng

Posts: 8
Registered: 2/24/18
Re: During the conversion process, I encountered some problems.Help,thank you
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 9:22 AM   in response to: huang weifeng in response to: huang weifeng
Try it a bunch of times, it's okay。
I use the "oleview" to view the parameters, and some of the parameters are required, but if I push it in, I can make a mistake. Both "open" methods are the same.
void __fastcall loadFromStream(TADODataSet *pvDataSet,TMemoryStream *pvStream)
{
   CoInitialize (0);
   int bounds[2] = {0, pvStream->Size-1};
   Variant s=VarArrayCreate(bounds,1, varByte);
   pvStream->Position=0;
   void *P=VarArrayLock(s);
   try {
	   Move(pvStream->Memory, P, pvStream->Size);
	   //pvStream->WriteBuffer(P,pvStream->Size);
   }
   __finally {
			VarArrayUnlock(s);
   }
   OleVariant V=s;
   //_di__Recordset RS =CoRecordset::Create();
   //_di__Stream AStream = CoStream::Create();
 
   Variant Stream=Variant(CreateOleObject("ADODB.Stream"));
   Stream.OleProcedure("Open");
   Stream.OlePropertySet("Type",1);
   Stream.OleProcedure("Write",V);
   Stream.OlePropertySet("Position",0);
 
   Variant Rs1=CreateOleObject("ADODB.Recordset");
   Rs1.OleProcedure("Open",Stream);
   Stream.OleProcedure("Close");
   pvDataSet->Recordset=_di_IDispatch(Rs1);
}
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: During the conversion process, I encountered some problems.Help,thank you [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 10:18 AM   in response to: huang weifeng in response to: huang weifeng
huang weifeng wrote:

During the conversion process, I encountered some problems. DELPHI is
converted into C++ Builder. Can you help me see what the problem is?

That code is mixing two different methodologies that should not be mixed together. Use either one methodology or the other, not both.

The first methodology uses the RTL's TStreamAdapter class to wrap the TMemoryStream in a standard COM IStream:

void loadFromStream2(TCustomADODataSet *pvDataSet, TMemoryStream *pvStream)
{
    pvStream->Position = 0;
    _di_IStream AStream(new TStreamAdapter(pvStream, TStreamOwnership::soReference));
    pvDataSet->Recordset->Open((IStream*)AStream, /*adPersistADTG*/0);
}


However, Microsoft's ADO documentation does not say that Open() supports loading from an IStream, only from an ADO Stream, which is what the second methodology uses:

void loadFromStream2(TCustomADODataSet *pvDataSet, TMemoryStream *pvStream)
{
    int bounds[] = {0, pvStream->Size - 1};
    OleVariant V(EXISTINGARRAY(bounds), varByte);
 
    void *P = V.ArrayLock();
    try {
        Move(pvStream->Memory, P, pvStream->Size);
    }
    __finally {
        V.ArrayUnlock();
    }
 
    _di__Stream AStream = CoStream::Create();
    AStream->Open(EmptyParam(), /*adModeUnknown*/0, /*adOpenStreamUnspecified*/-1, L"", L"");
    AStream->Type_ = /*adTypeBinary*/1;
    AStream->Write(V);
 
    _di__Recordset AR = CoRecordset::Create();
    AStream->Position = 0;
    AR->Open(AStream, EmptyParam(), /adOpenUnspecified*/-1, /*adLockUnspecified*/-1, /*adCmdUnspecified*/-1);
    pvDataSet->Recordset = AR;
}


I would suggest using a generic TStream instead, so you can load from any kind of streamable source (file, memory, etc) that the caller wants to use, eg:

void loadFromStream2(TCustomADODataSet *pvDataSet, TStream *pvStream)
{
    int size = pvStream->Size - pvStream->Position;
 
    int bounds[] = {0, size - 1};
    OleVariant V(EXISTINGARRAY(bounds), varByte);
 
    if (size > 0)
    {
        void *P = V.ArrayLock();
        try {
            pvStream->ReadBuffer(P, size);
        }
        __finally {
            V.ArrayUnlock();
        }
    }
 
    _di__Stream AStream = CoStream::Create();
    AStream->Open(EmptyParam(), /*adModeUnknown*/0, /*adOpenStreamUnspecified*/-1, L"", L"");
    AStream->Type_ = /*adTypeBinary*/1;
    AStream->Write(V);
    AStream->Position = 0;
 
    _di__Recordset AR = CoRecordset::Create();
    AR->Open(AStream, EmptyParam(), /adOpenUnspecified*/-1, /*adLockUnspecified*/-1, /*adCmdUnspecified*/-1);
    pvDataSet->Recordset = AR;
}


Alternatively:

void loadFromStream2(TCustomADODataSet *pvDataSet, TStream *pvStream)
{
    BYTE buffer[1024];
 
    _di__Stream AStream = CoStream::Create();
    AStream->Open(EmptyParam(), /*adModeUnknown*/0, /*adOpenStreamUnspecified*/-1, L"", L"");
    AStream->Type_ = /*adTypeBinary*/1;
 
    do
    {
        int size = pvStream->Read(buffer, sizeof(buffer));
        if (size <= 0) break;
 
        int bounds[] = {0, size - 1};
        OleVariant V(EXISTINGARRAY(bounds), varByte);
 
        void *P = V.ArrayLock();
        try {
            Move(buffer, P, size);
        }
        __finally {
            V.ArrayUnlock();
        }
 
        AStream->Write(V);
    }
 
    AStream->Position = 0;
 
    _di__Recordset AR = CoRecordset::Create();
    AR->Open(AStream, EmptyParam(), /adOpenUnspecified*/-1, /*adLockUnspecified*/-1, /*adCmdUnspecified*/-1);
    pvDataSet->Recordset = AR;
}


Or, you might even consider writing a custom class that wraps the TStream and implements ADO's _Stream interface, then AR->Open() could read data directly from the TStream without having to involve OleVariant at all.

--
Remy Lebeau (TeamB)
huang weifeng

Posts: 8
Registered: 2/24/18
Re: During the conversion process, I encountered some problems.Help,thank you [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 26, 2018 8:12 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thank you。my English is poor, I use translation software to translate into English, so there are problems in grammar, I'm sorry.
void loadFromStream2(TCustomADODataSet *pvDataSet, TMemoryStream *pvStream)
{
    pvStream->Position = 0;
    _di_IStream AStream(new TStreamAdapter(pvStream, TStreamOwnership::soReference));
    pvDataSet->Recordset->Open((IStream*)AStream, /*adPersistADTG*/0);
}

The above two lines of code compile with a hint of error.

void loadFromStream2(TCustomADODataSet *pvDataSet, TStream *pvStream)
{
    BYTE buffer[1024];
 
    _di__Stream AStream = CoStream::Create();
    //Variant(AStream).OleProcedure("Open");
    AStream->Open(EmptyParam(), /*adModeUnknown*/0, /*adOpenStreamUnspecified*/-1, L"", L"");
    AStream->Type_ = /*adTypeBinary*/1;
     int size=0
    do
    {
        size = pvStream->Read(buffer, sizeof(buffer));
        if (size <= 0) break;
 
        int bounds[] = {0, size - 1};
        OleVariant V(EXISTINGARRAY(bounds), varByte);
 
        void *P = V.ArrayLock();
        try {
            Move(buffer, P, size);
        }
        __finally {
            V.ArrayUnlock();
        }
 
        AStream->Write(V);
    }while(size>0)
 
    AStream->Position = 0;
 
    _di__Recordset AR = CoRecordset::Create();
    //Variant(AR).OleProcedure("Open",AStream);
    AR->Open(AStream, EmptyParam(), /adOpenUnspecified*/-1, /*adLockUnspecified*/-1, /*adCmdUnspecified*/-1);
    pvDataSet->Recordset = AR;
}

These two sentences have problems in C++ BuILDER, but the strange thing is that DELPHI is good.
AStream->Open(EmptyParam(), /*adModeUnknown*/0, /*adOpenStreamUnspecified*/-1, L"", L"");
AR->Open(AStream, EmptyParam(), /adOpenUnspecified*/-1, /*adLockUnspecified*/-1, /*adCmdUnspecified*/-1);

Variant(AStream).OleProcedure("Open");
Variant(AR).OleProcedure("Open",AStream);
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: During the conversion process, I encountered some problems.Help,thank you [Edit] [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 26, 2018 9:08 AM   in response to: huang weifeng in response to: huang weifeng
huang weifeng wrote:

_di_IStream AStream(new TStreamAdapter(pvStream,
TStreamOwnership::soReference));
pvDataSet->Recordset->Open((IStream*)AStream, /*adPersistADTG*/0);

The above two lines of code compile with a hint of error.

What hint exactly?

*These two sentences have problems in C++ BuILDER, but the strange
thing is that DELPHI is good.*

Again, WHAT PROBLEMS are you having? You keep saying that, but you
-aren't providing any details about them. I can't help you if you
don't show what is wrong.

AStream->Open(EmptyParam(),
/*adModeUnknown*/0, adOpenStreamUnspecified-1, L"", L"");

The 3rd parameter needs to be -1, not adOpenStreamUnspecified-1. In
the code I gave you earlier, I had adOpenStreamUnspecified commented
out for documentation purposes, just as I do for adModeUnknown.

AR->Open(AStream, EmptyParam(), adOpenUnspecified-1,
adLockUnspecified-1, adCmdUnspecified-1);

Same here. adOpenUnspecified, adLockUnspecified, adCmdUnspecified,
they should all be commented out.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02