We help IT Professionals succeed at work.

Equivalent C# alternative to Fortran Equivalence mapping

1,000 Views
Last Modified: 2013-11-08
I have a byte array of 25000 elements. How would I emulate Fortran Equivalence mapping in C# on the byte array?

byte[25000]

Comment
Watch Question

Meir RivkinFull stack Software Engineer
CERTIFIED EXPERT

Commented:
can u give short description of Fortran mapping?
Meir RivkinFull stack Software Engineer
CERTIFIED EXPERT

Commented:
if u mean declare byte array of 25000 then:
byte[] b = new byte[25000];

Author

Commented:
Fortran mapping description.

byte[] bt = new byte[25000]

reference sections of the byte[25000] array as array{n}.

byte[] array1 = bt[0:9]   (bytes from offset 0 to 9)
byte[] array2 = bt[10:29]

etc.  

Todd GerbertSenior Engineer
CERTIFIED EXPERT
Top Expert 2010

Commented:
I think it depends on what you want to do with the bytes...
Obviously you can reference bytes 0-9 by simply using indexes, bt[10], bt[11] ... bt[29]
You can make a copy of the array,

byte[] bt = new byte[25000];
byte[] subset = new byte[19];
Array.Copy(bt, subset, 19);
 
You can copy characters out into a string,
byte[] bt = new byte[25000];
string s = Encoding.ASCII.GetString(bt, 10, 19);

Author

Commented:
Thanks tGerbert,

I need to access data in the byte[25000] from the referenced array1, array2, etc.

My application needs to communicate with the byte[25000] array and my preference is to access it in manageable chunks via the smaller arrays.

Example:

byte[25000]
:::::::::::::::::
[0123456789012345678901234567890...
^                  ^                  ^
|                   |                   |

[ Array1      ][ Array2      ][etc...

AKA. "Subscripted Arrays"

Array1 = byte[] = 0-9
Array2 = byte[] = 10-19
etc.

When reading/changing bytes in the subscripted array, bytes are referenced and/or updated in the primary byte[25000] array at the offsets defined in the associated "subscripted array".

Author

Commented:
to be clear:

When reading/changing bytes in the subscripted array, bytes are referenced and/or updated in the primary byte[25000] array at the offsets as mapped by the associated "subscripted array".
Senior Engineer
CERTIFIED EXPERT
Top Expert 2010
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
tGerbert,

Over the weekend, reviewed the documentation of byte, IEnumerable, binaryreader, writer, memorystream  associated with what would otherwise appear as an easy operation. I tested your approach and the application needs to return the "substring array" which references the offset bytes.  Were I to return the ByteArray arg, would not bt[25000] be returned?

When the function created a new byte[] and returned it, I lost the references to bt[25000] primary array (array copy).
Todd GerbertSenior Engineer
CERTIFIED EXPERT
Top Expert 2010

Commented:
Here's an "unsafe" example.  Note that the compiler will not impose bounds checking - i.e. the compiler will happily allow a reference to array2[199], but would cause an error at runtime.
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

class Program
{
	const int ARRAY2_OFFSET = 10;
	const int ARRAY2_LENGTH = 19;

	static void Main(string[] args)
	{
		byte[] bt = new byte[100];
		
		unsafe
		{
			fixed (byte* array2 = &bt[10])
			{
				array2[0] = 55;
				Debug.Assert(bt[10] == array2[2]);
			}
		}
	}
}

Open in new window

Author

Commented:
An unsafe, though workable solution.

Many thanks!
Todd GerbertSenior Engineer
CERTIFIED EXPERT
Top Expert 2010

Commented:
If you care to give me a slightly more in-depth real-world example of what you're working to accomplish, I might be able to offer a more "acceptable" approach. ;)

Author

Commented:
Sure.

I can send the code offline. This is what I was trying to do.

Map an ODBC SQLBindCol and SQLBindParams columns to a single byte[25000] array. Each iterative call is mapped to fields in a row of data. The byte array can be considered the backing store for the associative bindings used by the two calls.

This is the solution.

Associate each ODBC binding to Marshal. class.
public void AllocBuffer(int length)
        {
            FreeBuffer();
            Handle = Marshal.AllocCoTaskMem(length);
            _length = length;
        }

Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.