[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Array of Byte to PChar

Posted on 2011-09-02
9
Medium Priority
?
2,771 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 38

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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

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
 
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 1000 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses

650 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