Re: Convert C-Builder program to Delphi?

M

Maarten Wiltink

Rudy Velthuis said:
Maarten Wiltink wrote:

Two kinds? Oh, you mean arrays and plain pointers? Now they have
references as well, IIRC. C++ most certainly has them.

No, worse than that. Pointers and references were the two types I
had in mind. The upcoming 2005 ECMA (2006 ISO/IEC) C++ standard
includes .Net support which segregates out pointers into the
garbage-collected heap, now called "handles" and declared with ^
instead of *... but dereferenced with * like the old pointers.
This is a compatibility feature so code using either old or new
pointers can be generic.

Groetjes,
Maarten Wiltink
 
W

W. D.

Maarten said:
W. D. said:
Maarten Wiltink wrote:

Good question. I am trying to duplicate the C++ code,
and that is how it is written.

C does not have var parameters. So when you need one, you
pass a pointer to your variable. You'll notice that all
the traditional-style I/O functions in Pascal (WriteLn for
example) pass the file variable by reference.

[...]
Does anyone know the equivalent of C++'s 'Delete[]' in
Delphi?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// C++: char *RawData;
RawData: PChar;

// C++: FieldTyypes *The_Fields;
The_Fields: FieldTyypesPtr;


// C++: SOMEDB::~SOMEDB()
Destructor SOMEDB.Destroy;

// C++: {
Begin

delete[] RawData;
delete[] The_Fields;

// C++: }
End; // Destructor SOMEDB.Destroy;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It looks like an array deallocator. If you translated these things into
dynamic arrays, letting the references go out of scope should be enough.
If you want to be explicit about it, SetLength() them to zero elements.
(Personally, I don't like setting things that aren't pointers to nil,
and arrays aren't pointers in the language even if they are in an
implementation.)

Hmmm. I set them to NIL and it compiled. We'll see if it runs--
eventually.
 
W

W. D.

Arrrrrgh! Pointers were invented by Satan!

These appear to be pointers to functions. I can't seem to find
many examples of Delphi 'method pointers'. Do any of you
have an idea of what would be appropriate?

typedef void (*ProcessPkt)(const DlPkt *p);

typedef bool (*DL_Msg)(uint32 CurPktCnt, uint32 BytsRcvd, uint32
TtlExptd, const DlPkt *p);

typedef bool (*DLabortSgnl)(bool BfrAbort);

void SetDlCommMsg(ProcessPkt FunctionPtr);


Thanks dudes, for your previous answers and any help you can
provide on this one!
 
I

Ioannis Vranos

W. D. said:
Arrrrrgh! Pointers were invented by Satan!

These appear to be pointers to functions. I can't seem to find
many examples of Delphi 'method pointers'. Do any of you
have an idea of what would be appropriate?

typedef void (*ProcessPkt)(const DlPkt *p);

typedef bool (*DL_Msg)(uint32 CurPktCnt, uint32 BytsRcvd, uint32
TtlExptd, const DlPkt *p);

typedef bool (*DLabortSgnl)(bool BfrAbort);

void SetDlCommMsg(ProcessPkt FunctionPtr);


Thanks dudes, for your previous answers and any help you can
provide on this one!


Do not get upset with that, but what you are trying to do is convert
from a powerful language to one less powerful, and you can't do that in
a straightforward way (while the opposite can be done). Unavoidably you
will have to change many things in the code to imitate around how things
are being done in the code, so as to complete the conversion.


I do not remember much of C++Builder, but if Delphi and C++Builder can
create compatible dlls among them, then you may encapsulate the C++ code
in a dll under one or more classes or functions, and use that dll in
your Delphi code.
 
I

Ioannis Vranos

Maarten said:
No, worse than that. Pointers and references were the two types I
had in mind. The upcoming 2005 ECMA (2006 ISO/IEC) C++ standard


Actually it is C++/CLI, a standard of *extensions* to ISO C++ to take
advantage of a CLI machine where one is available.


includes .Net support which segregates out pointers into the
garbage-collected heap, now called "handles" and declared with ^
instead of *... but dereferenced with * like the old pointers.
This is a compatibility feature so code using either old or new
pointers can be generic.


At first, with the arrival of VC++ 2005 and C++/CLI standard, C++
becomes the systems programming language of .NET.


Take a look at these:


http://msdn.microsoft.com/msdnmag/issues/05/01/COptimizations/default.aspx

http://pluralsight.com/blogs/hsutter/archive/2004/10/05/2672.aspx

http://blogs.msdn.com/branbray/archive/2003/11/07/51007.aspx

http://www.accu.org/conference/pres...Relevant_on_Modern_Environments_(keynote).pdf


And a page of mine:

http://www23.brinkster.com/noicys/cppcli.htm



Now some more on this:

With C++/CLI, C++ has two worlds: The unmanaged world and the managed world.

In the managed world every CLI (.NET) feature is provided separately
from the unmanaged world features.
 
M

Maarten Wiltink

Ioannis Vranos said:
W. D. wrote:

Reading the help is always appropriate. Watch out for the difference
between regular procedures and methods.


type
ProcessPkt = procedure(var p: DlPkt);
DL_Msg = function(Cardinal CurPktCnt; Cardinal BytsRcvd;
Cardinal TtlExptd; var p: DlPkt): Boolean;
DLabortSgnl = function(BfrAbort: Boolean): Boolean;

procedure SetDlCommMsg(FunctionPtr: ProcessPkt); forward;

There may be a cdecl or two missing in there if you want to interface
directly with compiled C code.

Do not get upset with that, but what you are trying to do is convert
from a powerful language to one less powerful,

Bollocks. Procedural types are _exactly_ as powerful in either language.

Groetjes,
Maarten Wiltink
 
J

Jamie

W. D. said:
Arrrrrgh! Pointers were invented by Satan!

These appear to be pointers to functions. I can't seem to find
many examples of Delphi 'method pointers'. Do any of you
have an idea of what would be appropriate?

typedef void (*ProcessPkt)(const DlPkt *p);

typedef bool (*DL_Msg)(uint32 CurPktCnt, uint32 BytsRcvd, uint32
TtlExptd, const DlPkt *p);

typedef bool (*DLabortSgnl)(bool BfrAbort);

void SetDlCommMsg(ProcessPkt FunctionPtr);


Thanks dudes, for your previous answers and any help you can
provide on this one!
your making it hard on your self.

here are some tips
a procedure in delphi can be past to as a reference via the
@ infront of the procedure. kind in mind that you should be using
the calling convention that is expected, for example a "STDCALL" tagged
at the end of the procedure header/
etc..
if you really want to have procedure pointers., you can do this.
var
myprocedurename:procedure(the params):stdcall; // if needed ..

some where in your code you simply set it from an address.
etc...
this is just some insight for you.
 
B

Bruce Roberts

Do not get upset with that, but what you are trying to do is convert
from a powerful language to one less powerful, and you can't do that in
a straightforward way (while the opposite can be done). Unavoidably you
will have to change many things in the code to imitate around how things
are being done in the code, so as to complete the conversion.

I have to quibble with your characterization of C as a more powerful
language than Delphi. If one were to try and translate a complex assembly
language program to C, I presume that you would characterize assembly as
"more powerful"?

Its not a question of how "powerful" a language is or isn't. Especially
since "powerful" is a subjective term with no consensus as to what it means.
Certainly not how it can be measured.

When translating between any two languages, but especially two that do not
share a common cultural background, one can have difficulty. One will always
find things expressible in one that have no real translation into the other.
It doesn't matter if one is translating natural or formal languages. The
culture in and represented by a language makes a real difference.
 
W

W. D.

Thanks again Maarten, Walter, Jamie & Jim!!!

I now seem to be getting an error when comparing the
difference of 2 pointer addresses:

"Operator not applicable to this operand"

Here is some code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Type

ByteArray = Array [0..$0FFFFFFF] of Byte;
ByteArrayPtr = ^ByteArray;

uint8Array = Array [0..$0FFFFFFF] of uint8;
uint8ArrayPtr = ^uint8Array;

uint8Ptr = ^uint8;


Var

ByteAryPtr: ByteArrayPtr;
uint8AryPtr: uint8ArrayPtr

cp: uint8Ptr;


// C++: uint8 *cp = &ThePort->Pkt.data[16]; // 'ThePort' is a class
pointer
uint8AryPtr := Pointer(@ThePort.Pkt.data);
cp := uint8Ptr(uint8AryPtr[16]);

ByteAryPtr := Pointer(@ThePort.Pkt.data);

// C++: while (*cp != 0x1A && cp - (&ThePort->Pkt.data[16]) < 82)
While (
(cp^ <> $1A)
AND
( (cp - (@ByteAryPtr[16])) < 82 ) // <-- "Operator not
applicable to this operand"
) Do

Begin
// Do stuff
End;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the above C code, does '82' mean decimal 82? Is there
some other way this number should be written? It would
seem to me to be legal to determine the difference between
to addresses.

Also, is this kludgy code the proper way to index
pointers?

Thanks for any light you can shed!!!
 
M

Maarten Wiltink

[...]
I now seem to be getting an error when comparing the
difference of 2 pointer addresses:

"Operator not applicable to this operand"

The help (for "pointer operators") suggests you can only subtract
PChars.

Here is some code:

In the above C code, does '82' mean decimal 82? Is there
some other way this number should be written?

0x82 = hexadecimal 82, 130 decimal
082 = octal 82, 66 decimal
82 = decimal 82

Delphi has $82 for hex and no equivalent for octal.


[...]
Also, is this kludgy code the proper way to index
pointers?

Indexing pointers is not problematic. P = (P+i)^, and @P is P+i
(and the latter should be written P+i, IMO).

Groetjes,
Maarten Wiltink
 
J

Jamie

W. D. said:
Here is some code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Type

ByteArray = Array [0..$0FFFFFFF] of Byte;
ByteArrayPtr = ^ByteArray;

uint8Array = Array [0..$0FFFFFFF] of uint8;
uint8ArrayPtr = ^uint8Array;

uint8Ptr = ^uint8;


Var

ByteAryPtr: ByteArrayPtr;
uint8AryPtr: uint8ArrayPtr

cp: uint8Ptr;


// C++: uint8 *cp = &ThePort->Pkt.data[16]; // 'ThePort' is a class
pointer
uint8AryPtr := Pointer(@ThePort.Pkt.data);
cp := uint8Ptr(uint8AryPtr[16]);

ByteAryPtr := Pointer(@ThePort.Pkt.data);

// C++: while (*cp != 0x1A && cp - (&ThePort->Pkt.data[16]) < 82)
While (
(cp^ <> $1A)
AND
( (cp - (@ByteAryPtr[16])) < 82 ) // <-- "Operator not
applicable to this operand"
) Do

Begin
// Do stuff
End;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the above C code, does '82' mean decimal 82? Is there
some other way this number should be written? It would
seem to me to be legal to determine the difference between
to addresses.
i would like the see the original code, i think really have it messed up.
any ways, you can use inc/dec on typed pointers., it will increment the
pointer in the correct range to match the type size.
for example.
if the pointer was an integer (4 bytes), the pointer would have 4
added to it when you do a inc(integerPointer, 1);
in your problem line above, you could case the whole statement into
integers to perform the math.
if Pbyte(dword(cp)-dword(@byteAryptr[16]))^ < 82 then ...
that may give you some insight.
 
N

Nicolai Hansen

Maarten Wiltink said:
Ah yes, that rings a bell. Something about the latest C (C++?)
standard thinking two kinds of pointers weren't enough and
adding a third.

Groetjes,
Maarten Wiltink

C# has an "out" keyword or something for this doesn't it? I don't
recall seeing it in C++ though.
 
M

Maarten Wiltink

Nicolai Hansen said:
"Maarten Wiltink" <[email protected]> wrote in message
C# has an "out" keyword or something for this doesn't it? I don't
recall seeing it in C++ though.

C# has really very little to do with C/C++. In hiding pointers from
the user, it's (unsurprisingly) much more like Pascal.

There are "ref" and "out" modifiers on parameters in C#. The only
difference with "var" and "out" in Delphi is that you have to
repeat them in the function _call_.

Groetjes,
Maarten Wiltink
 
W

W. D.

Thanks Maarten, Stephen, Jamie & Cosmind for your help!!!

I am now getting an "Incompatible Types" error when assigning
an instance of a class to a pointer. I am using the
Constructor as recommended but I still don't understand why
I am getting error. Any clues available?


// C++: ClassPtr = new (ComClass_Serial(port, baudrate, rx_size,
tx_size));

ClassPtr := ComClass_Serial.Create(port, baudrate, rx_size, tx_size);
 
M

Maarten Wiltink

I am now getting an "Incompatible Types" error when assigning
an instance of a class to a pointer. I am using the
Constructor as recommended but I still don't understand why
I am getting error. Any clues available?


// C++: ClassPtr = new (ComClass_Serial(port, baudrate, rx_size,
tx_size));

ClassPtr := ComClass_Serial.Create(port, baudrate, rx_size, tx_size);

Please ask better questions. Show us the delcaration of ClassPtr, the
declaration of ComClass_Serial.Create, the exact error message, and
the point where the compiler reports it.

Object Pascal is a strongly typed language. Any errors against the
typing system should be fairly obvious.

Groetjes,
Maarten Wiltink
 
J

Jamie

W. D. said:
Thanks Maarten, Stephen, Jamie & Cosmind for your help!!!

I am now getting an "Incompatible Types" error when assigning
an instance of a class to a pointer. I am using the
Constructor as recommended but I still don't understand why
I am getting error. Any clues available?


// C++: ClassPtr = new (ComClass_Serial(port, baudrate, rx_size,
tx_size));

ClassPtr := ComClass_Serial.Create(port, baudrate, rx_size, tx_size);
declare the class pointer as.

Var
ClassPtr:TComClass_Serial;

classes are already pointers of their own type.

Give it some meaningful name.
 
W

W. D.

Hi Folks,

Many thanks for all the help you have provided!!

Currently, I am getting several of these errors:

'Unsatisfied forward or external declaration'

They occur in the Interface section, even though several
versions of these Overloaded functions are in the
Implementation section (and otherwise compile OK).

One would think that if they exist in the Implematation
section, and they didn't match the templates in the
Interface section, there would be some sort of
mismatch error. But for some reason, the compiler
doesn't think they exist.

I've gotten this type of error when the functions were
owned by a Class. The solution is to prepend the
name of the class onto the function:

TheFunction();

becomes:

TheClassName.TheFunction();


Since these functions aren't contained in a class, what
could be preventing the compiler from finding them?


Again, many thanks for any hints you can provide!
 
M

Maarten Wiltink

Currently, I am getting several of these errors:

'Unsatisfied forward or external declaration'

They occur in the Interface section, even though several
versions of these Overloaded functions are in the
Implementation section (and otherwise compile OK).

One would think that if they exist in the Implematation
section, and they didn't match the templates in the
Interface section, there would be some sort of
mismatch error. But for some reason, the compiler
doesn't think they exist.

Overloading makes this harder for the compiler.

I've gotten this type of error when the functions were
owned by a Class. The solution is to prepend the
name of the class onto the function:

TheFunction();

becomes:

TheClassName.TheFunction();


Since these functions aren't contained in a class, what
could be preventing the compiler from finding them?

Hard to say without seeing code. Stripped-down code, please.
Ten to one you'll find the error you made before ever posting.

The ground rule is quite simple. "The compiler is always right."

Groetjes,
Maarten Wiltink
 
J

Jamie

W. D. said:
Hi Folks,

Many thanks for all the help you have provided!!

Currently, I am getting several of these errors:

'Unsatisfied forward or external declaration'

They occur in the Interface section, even though several
versions of these Overloaded functions are in the
Implementation section (and otherwise compile OK).

One would think that if they exist in the Implematation
section, and they didn't match the templates in the
Interface section, there would be some sort of
mismatch error. But for some reason, the compiler
doesn't think they exist.

I've gotten this type of error when the functions were
owned by a Class. The solution is to prepend the
name of the class onto the function:

TheFunction();

becomes:

TheClassName.TheFunction();


Since these functions aren't contained in a class, what
could be preventing the compiler from finding them?


Again, many thanks for any hints you can provide!
I don't understand what your saying, you state they are
in the interface and implementation section but you can only
access them via a Class name space?
is it possible your trying to expose some members of a
class into the interface section?, if so that can not be
done.
 
W

W. D.

Thanks Maarten, Walter, and Jamie.

The solution to my 'Unsatisfied forward or external declaration'
error was that there were slight differences in the integer
types in the different declarations. To find this out, I
copied the declarations into a text editor--Interface on
top, Implementation on the bottom--then compared the two.
The type differences then were apparent.

I am still struggling with pointers and indexing them. The
current code I am trying to convert is contained in
some nested FOR loops:

===============================================================
A_RecordPtr: ^SomeRecordType;
i: uint32;
j: uint32;
pAuthDB: ^SomeOtherRecordType;


if
(A_RecordPtr.SomeBoolFunc(TransposeByteOrder(*(uint32*)&pAuthDB[j].DBID)))
===============================================================

How can I handle this without getting the dreaded
"Array Type Required" error?

Many thanks for your insight!!!!!!!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,293
Messages
2,571,500
Members
48,188
Latest member
GerardRush

Latest Threads

Top