How to get a Byte Array ?

Using (or providing) Microsoft.NET Classes

How to get a Byte Array ?

Postby PGilbert on Sat Aug 07, 2010 3:48 am

I am trying to build a .Net Byte Array and can't make it work, what is the proper syntax for Unicode v12.1 ? The following does not work:

⎕NEW Convert.ToByte (a number between 0 and 255)

Thanks in advance,

Pierre Gilbert
User avatar
PGilbert
 
Posts: 440
Joined: Sun Dec 13, 2009 8:46 pm
Location: Montréal, Québec, Canada

Re: How to get a Byte Array ?

Postby Vince|Dyalog on Mon Aug 09, 2010 11:02 am

Hi Pierre,

I think you can just give an array of numbers in the range 0 to 255.

As an example:
BitConverter.ToInt32 takes a byte array as its first argument.

⎕USING←'System'
a←BitConverter.GetBytes 123456789
BitConverter.ToInt32 a 0
123456789
b←255 255 255 255
BitConverter.ToInt32 b 0
¯1
BitConverter.ToInt32 (255 0 0 0) 0
255

Regards,

Vince
Vince|Dyalog
 
Posts: 443
Joined: Wed Oct 01, 2008 9:39 am

Re: How to get a Byte Array ?

Postby PGilbert on Tue Aug 10, 2010 12:18 am

Thanks Vince for your reply, you made me realized that I don't need a ⎕NEW for doing this. Here is what's work for me in v12.1 Unicode:

Convert.ToByte¨ ⎕ucs (a number from 0 to 255)

Pierre Gilbert
User avatar
PGilbert
 
Posts: 440
Joined: Sun Dec 13, 2009 8:46 pm
Location: Montréal, Québec, Canada

Re: How to get a Byte Array ?

Postby PGilbert on Fri Aug 13, 2010 8:43 pm

If I do the following:

     Convert.ToByte 34
34

the .Net Object that is returned is reverted to an APL number. What do I need to do to keep the result as a .Net Byte[] Object ?

Thanks in advance,

Pierre Gilbert
User avatar
PGilbert
 
Posts: 440
Joined: Sun Dec 13, 2009 8:46 pm
Location: Montréal, Québec, Canada

Re: How to get a Byte Array ?

Postby RossHale on Sat Aug 14, 2010 12:17 am

Hi Pierre,

I have not found a really satisfactory way to hold on to a .Net type that the APL interpreter
coerces to a numeric APL value. A general work around has been to set up my own utility .dll in C#
to do type conversions on the C# side by overloading set functions for properties
or overloading method or function arguments to have a variety of likely C# (numeric?) types.

It would seem (to me) that a possible way to improve on this would be to use some of the .Net
collection data types such as Array where you create a collection of a given base type from within APL.
APL handles some of these collections elegantly. There are interesting facilities for transforming one
collection to another with the possibility of converting values from one base type to another.

⎕using←'System' 'System.IO'
z←Array.CreateInstance(System.Byte 1) ⍝ zero-based array (to .NET) of length 1 of System.Byte

I have not really worked this out.

Ross
User avatar
RossHale
 
Posts: 31
Joined: Thu Jun 18, 2009 9:08 pm
Location: Bellevue, Washington, USA

Re: How to get a Byte Array ?

Postby PGilbert on Sat Aug 14, 2010 1:55 pm

Thanks Ross for your reply. If I want to populate the Byte array I should be able to do this:

⍝ Creates an Empty Byte Array of 100 elements
z←Array.CreateInstance (System.Byte 100)

⍝ The number 100 is supposed to be an Int32. Is it converted automatically ?
z←Array.CreateInstance(System.Byte) (Convert.ToInt32 100) ⍝ This works as well

⍝ Now if I want to set the number 50 in position 1 I should be able to use .SetValue like this:
z.SetValue (Convert.ToByte 50) (Convert.ToInt32 1) ⍝ Does not work
z.SetValue ((Convert.ToByte 50) 1) ⍝ Does not work either

The error is:
Cannot widen from source type to target type either because the source type is a not a primitive type or the conversion cannot be accomplished.

What is it that I am doing wrong ?

Thanks in advance,

Pierre Gilbert
User avatar
PGilbert
 
Posts: 440
Joined: Sun Dec 13, 2009 8:46 pm
Location: Montréal, Québec, Canada

Re: How to get a Byte Array ?

Postby PGilbert on Sat Aug 14, 2010 11:42 pm

RossHale wrote:I have not found a really satisfactory way to hold on to a .Net type that the APL interpreter
coerces to a numeric APL value.


With MicroAPL there is a way to force the result to stay on the .Net side: you add .⎕REF at the end of the .Net statement. For example, one way I found to get a byte array is to populate a MemoryStream and afterward use the method .ToArray to obtain a Byte[] array:

ms ← ⎕new MemoryStream ⍝ Creates an empty MemoryStream

ms.WriteByte¨ ⎕ucs 'abcd' ⍝ Populates the MemoryStream with the bytes 'abcd'

ms.ToArray.⎕Ref ⍝ Would return a Byte[] array with MicroAPL

Also MicroAPL have a .⎕Val to obtain the value of a .Net Object that is on the .Net side.

Is there is an equivalent in Dyalog APL for .⎕Ref ?

Thanks,

Pierre Gilbert
User avatar
PGilbert
 
Posts: 440
Joined: Sun Dec 13, 2009 8:46 pm
Location: Montréal, Québec, Canada

Re: How to get a Byte Array ?

Postby Vince|Dyalog on Mon Aug 16, 2010 11:44 am

Hi Pierre,

We will take a look at this to see if this is a bug in our .Net Interface.

PGilbert wrote:⍝ Now if I want to set the number 50 in position 1 I should be able to use .SetValue like this:
z.SetValue (Convert.ToByte 50) (Convert.ToInt32 1) ⍝ Does not work
z.SetValue ((Convert.ToByte 50) 1) ⍝ Does not work either

The error is:
Cannot widen from source type to target type either because the source type is a not a primitive type or the conversion cannot be accomplished.


Regards,

Vince
Vince|Dyalog
 
Posts: 443
Joined: Wed Oct 01, 2008 9:39 am

Re: How to get a Byte Array ?

Postby Vince|Dyalog on Mon Aug 16, 2010 12:55 pm

Hi Pierre,

PGilbert wrote:Is there is an equivalent in Dyalog APL for .⎕Ref ?


Have a look at page 27 of the Dyalog .Net Interface Guide. We have a Dyalog .Net Class called ByRef to provide you with a mechanism for dealing with pointers.

I do not know if this does what you want, but I just thought you should be aware of it.

Regards,

Vince
Vince|Dyalog
 
Posts: 443
Joined: Wed Oct 01, 2008 9:39 am

Re: How to get a Byte Array ?

Postby RossHale on Mon Aug 16, 2010 9:27 pm

⍝ How tyo get a Byte (or other System.Type) Array?
⎕io←0 ⍝ zero indexing to match .Net array zero-based indexing
⎕using←'' 'System' 'System.Collections' ⍝ add other entries as needed

ba←System.Array.CreateInstance (System.Type.GetType⊂'System.Int16') 3 ⍝ 3 element array System.Int16[]
bax←System.Collections.ArrayList.Adapter ba ⍝ wrapper for ba

⍝ now it is fairly easy to assign values in APL fashion to bax and hence to ba
bax[0 1 2]←34 55 66 ⍝ the ArrayList provides property rules assignment and respects the type of ba (System.Int16)

bax.ToArray⍬ ⍝ yields an APL array with values derived from here the System.Int16 values
bax.ToArray (System.Type.GetType⊂'System.Int16') ⍝ as above
bax.ToArray (System.Type.GetType⊂'System.Int32') ⍝ as above after widening behind the scenes to System.Int32

⍝ Now you can achieve some other type conversions, sometimes after using a System.Convert provided conversion
bax[⍳bax.Count]←Convert.ToByte¨⌷bax ⍝ explicit conversion to "narrow" types
⌷bax
34 55 66
bax.ToArray System.Type.GetType⊂'System.Int64' ⍝ Looks like conversion can "widen" types with some ease
32 55 66
⎕dr bax.ToArray System.Type.GetType⊂'System.Int64'
326
⎕dr t←bax.ToArray System.Type.GetType⊂'System.Int64'
326
t[0]
32
(t[0]).⎕nl -2
MaxValue MinValue
t[0].GetType
System.Int64

mz64←System.Array.CreateInstance (System.Type.GetType⊂'System.Int64') bax.Count
bax.CopyTo mz64


User avatar
RossHale
 
Posts: 31
Joined: Thu Jun 18, 2009 9:08 pm
Location: Bellevue, Washington, USA

Next

Return to Microsoft.NET

Who is online

Users browsing this forum: No registered users and 1 guest