Solved

Array of Byte to PChar

Posted on 2011-09-02
9
2,405 Views
Last Modified: 2012-05-12
I am converting a DLL to XE from D7 and need to convert an array of Byte that is passed in to a PChar that can be passed to a StrMove.

I could write my own ByteMove, but am needing a similar conversion in other spots that are more complicated to explain.  

 
procedure Transpose(var Data, OrderData: array of Byte);
var
  TmpData: array[0..63] of Byte;
  i : Byte;
begin
  StrMove(@TmpData, @Data, SizeOf(Data));
  for i := 0 to High(OrderData) do
    Data[i] := TmpData[OrderData[i]];
end;

Open in new window


With D7 this worked.  But with the new PWideChar support in D2009+ it will not.
0
Comment
Question by:GNiessen
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 36475089
the clue is what you are passing to this procedure
and what are you trying to accomplish ?

the context of what you are doing is odd for unicode strings

have you checked the functions StringOf and BytesOf ?
0
 
LVL 3

Expert Comment

by:VahaC
ID: 36475195
in <=D2007 PChar = PAnsiChar, Char = AnsiChar
in D2009+ PChar = PWideChar, Char = WideChar

SizeOf(PAnsiChar) = 1Byte
SizeOf(PWideChar) = 2Byte


try to run this code in different versions of delphi
  ShowMessage(Format('Size of "AnsiChar" %d, Size of "WideChar" %d, Size of "Char" %d', [SizeOf(AnsiChar), SizeOf(WideChar), SizeOf(Char)]));

Open in new window

0
 
LVL 3

Expert Comment

by:VahaC
ID: 36475201
I wrote wrong
SizeOf(PAnsiChar) = 1Byte
SizeOf(PWideChar) = 2Byte
must be
SizeOf(AnsiChar) = 1Byte
SizeOf(WideChar) = 2Byte
0
 

Author Comment

by:GNiessen
ID: 36475262
In this case I have a fixed Byte Array of 64 characters getting passed in from another system.  There is some encryption being done that make accessing them as bytes more efficient then as an array of characters,  This is legacy code, so it is all AnsiChar.    I am not looking to make it Unicode enabled at this time.  
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 3

Expert Comment

by:brezniczky
ID: 36476506
I guess you only need to get rid of the string based approach, and handle data simply as bytes instead.

procedure Transpose(var Data, OrderData: array of Byte);
var
  TmpData: array[0..63] of Byte;
  i : Byte;
begin
  Move(Data, TmpData, SizeOf(Data));
  for i := 0 to High(OrderData) do
    Data[i] := TmpData[OrderData[i]];
end;

Open in new window


It may worth thinking it over to pass PByte pointers to a function that expected PAnsiChar parameters, since it may lead to maintainability problems. I mean, finding a function with another parameter type is a good trail, even to another possible solution using the CopyMemory API as well.
0
 
LVL 3

Expert Comment

by:brezniczky
ID: 36476524
Hello,

I guess you only need to get rid of the otherwise suspicious parameter passing - I mean, the StrMove expects PAnsiChars (in D7), so it should not deal with PByte pointers. You could move the data in a loop yourself byte by byte, or use one of the handful of functions like CopyMemory, MoveMemory, Move, etc..
As for me, I would prefer using Move as it seems to be the native solution:

procedure Transpose(var Data, OrderData: array of Byte);
var
  TmpData: array[0..63] of Byte;
  i : Byte;
begin
  Move(Data, TmpData, SizeOf(Data));
  for i := 0 to High(OrderData) do
    Data[i] := TmpData[OrderData[i]];
end;

Open in new window

0
 
LVL 13

Expert Comment

by:ThievingSix
ID: 36478451
" I mean, the StrMove expects PAnsiChars (in D7), so it should not deal with PByte pointers. "

Well, they are technically both pointers, hence why it works fine.
0
 
LVL 3

Accepted Solution

by:
brezniczky earned 250 total points
ID: 36478638
Well, I do not know if the author's concern ("But with the new PWideChar support in D2009+ it will not.") is realistic, since I have no D 2009+ on hand.

On the other hand, I see the online XE documentation showing two overloads for StrMove - there is one dealing with PAnsiChars and one with PWideChars.

Even if the code works fine - of which I am unsure - I would not dare to state it is not ambiguous for the compiler to determine which overload matches such a situation (pointer, pointer, integer).

Furthermore, for testing, I reproduced this with D7, so I received an "Ambiguous overloaded call to ..." error. Explicitly using a PAnsiChar typecast will most likely remedy the situation among the other solutions outlined above.

Like I expect

procedure Transpose(var Data, OrderData: array of Byte);
var
  TmpData: array[0..63] of Byte;
  i : Byte;
begin
  StrMove(PAnsiChar(@TmpData), PAnsiChar(@Data), SizeOf(Data));
  for i := 0 to High(OrderData) do
    Data[i] := TmpData[OrderData[i]];
end;

Open in new window


to be a syntactically correct, more explicit and therefore descriptive code piece.
0
 

Author Closing Comment

by:GNiessen
ID: 36489873
While I agree with your comments on the ByteArray, sometimes there are reasons to not change things any more then required to make it work again.  So I will go with the StrMove and PAnsiChar.  Which was what I did and tested before, but was not sure it was the best or definitive solution.  And this might not have been the best example of what I have in other areas, but seems to have worked.  

Thanks
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Machine not responding during CopyFile() 3 88
Delphi TcxGrid group footer summary 3 203
Correct Component for Shopping Cart. 2 95
Delphi inherited method 6 61
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
A short film showing how OnPage and Connectwise integration works.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now