?
Solved

Array of Byte to PChar

Posted on 2011-09-02
9
Medium Priority
?
2,693 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses
Course of the Month11 days, 16 hours left to enroll

752 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