In a class definition, I implemented IList<T> to make it look like an array.
// Foo has C++ arrays inside for a
// fast communication with some hardware
public abstract class Foo<T> : IList<T(or uint for a derived class)>
{
public virtual void CopyTo(uint[] array, int arrayIndex)
{
int dL = Length;
if (dL == array.Length)
{
/* needs pinning the target before this?*/
Marshal.Copy(handleForFooUnmanagedArray,
(int[])(object) array,
arrayIndex,
dL - arrayIndex);
return;
}
throw new NotImplementedException();
}
}
so it can do this now:
uint [] bar = new uint[L];
foo.CopyTo(bar,0);
but now I want to make it work like an array with this:
uint [] bar = new uint[L];
bar.CopyTo(foo,0);
so I looked what interfaces an array implements in run-time(here) to find something like a private .CopyFrom that I thought should be called implicity in `.CopyTo',
IList
ICloneable
ICollection
IEnumerable
IStructuralComparable
IStructuralEquatable
non of these have any .CopyFrom.
Maybe there is some IntPtr property as a handle for Marshal copying in .CopyTo but I couldn't see it in intellisense.
Question:
How can I find that which method does the .CopyTo use to get necessary info about target array and what that necessary info would that be? Another method like a .CopyFrom or a handle pointing to start of target array, or some interpreter intermediate codes stored in somewhere? Is the target array pinned in the process?
Side question:
Do I need to implement some extra methods in IList<T> on top of important(unknown) ones?
I already implemented toArray, Count and [] but I havent done anything for others yet. Then Foo also has Length(with a custom interface) but it doesn't belong Array so an uint[] may not use it in its CopyTo.
I'm not experienced with IL so I may not understand if thats the solution but I can look back in time.
Also I tried to implement Array which refuses to be implemented because of being a special class.
Thank you very much for your time.
CopyTo is implemented in unmanaged code by runtime itself, and signature of method looks like this:
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);
As you see it still expects Array and not some pointer, so it's hard to do what you want.
But if you can have a managed array inside your Foo then it's easy to achieve the goal - just use implicit conversion to Array like this:
class MyFakeArray {
uint[] _realArray = new uint[10];
public MyFakeArray() {
}
public static implicit operator uint[](MyFakeArray a) {
return a._realArray;
}
}
Then CopyTo will work as expected:
var a = new uint[10];
var fa = new MyFakeArray();
a.CopyTo(fa, 0);
I have the following simplified function:
private IEnumerable<byte> Encode(IEnumerable<byte> Input)
{
computation();
return result;
}
The Buffer:
byte[] BufferHex = {0x00};
IEnumerable<byte> result1;
richtext.AppendText(Encoding.UTF8.GetString(result1));
The error is at the last line saying: Conversion IEnumerable to byte[] not possible.
I have tried several things but still no success. Any help will be appreciated.
As it says it is expecting a byte[] as parameter, so you need to convert your IEnumerable<byte> to a byte[], you can do this using ToArray extension method:
richtext.AppendText(Encoding.UTF8.GetString(result1.ToArray()));
Encoding.UTF8.GetString() expects a parameter of type byte[], not IEnumerable<byte>. So simply change that line to
richtext.AppendText(Encoding.UTF8.GetString(result1.ToArray()));
ToArray() is a LINQ extension that converts an IEnumerable<T> into a T[].
I don't know if this will be suitable for your case, but you can use Convert.ToBase64String(byte[] bytes) and don't forget to call ToArray(), on your enumerable
I am writing a function to help serialize data to pass through a socket. I wanted to write a small function that would serialize one item.
private byte[] SerializeOne<T>(T data)
{
byte[] oneItem = new byte[Constants.ONE_ITEM_BUFFER];
oneItem = BitConverter.GetBytes(data);
if (BitConverter.IsLittleEndian)
oneItem.Reverse();
return oneItem; }
The problem is BitConverter alwaysassumes data is a type bool and throws this error: Argument 1 cannot convert from T to bool. Am I missing some syntax to force BitConverter to use the T type or is this not possible in C#?
I want to make a list of pointers to locations that contains a certain value in the process memory of another process. The value can be a short, int, long, string, bool or something else.
My idea is to use Generics for this. I have one problem with making it, how can I tell the compiler to what type he needs to convert the byte array?
This is what I made:
public List<IntPtr> ScanProccessFor<T>(T ItemToScanFor)
{
List<IntPtr> Output = new List<IntPtr>();
IntPtr StartOffset = SelectedProcess.MainModule.BaseAddress;
int ScanSize = SelectedProcess.MainModule.ModuleMemorySize;
for (int i = 0; i < ScanSize; i++)
if (ReadMemory(SelectedProcess, StartOffset + i, (UInt16)Marshal.SizeOf(ItemToScanFor)) == ItemToScanFor)
Output.Insert(Output.Count,StartOffset + i);
return Output;
}
How can I tell the compiler that he needs to convert the byte[] to type T?
Your question is a little bit confusing, but I'll try to answer what I can
Instead of taking a generic type, I would probably write a method that takes an instance of an interface like IConvertableToByteArray or something.
public IConvertableToByteArray
{
public byte[] ToByteArray();
}
Then If you needed to allow a specific type to be compatible with that method, you could make an encapsulating class
public IntConvertableToByteArray : IConvertableToByteArray
{
public int Value{get; set;}
public byte[] ToByteArray()
{
insert logic here
}
}
You could use Marshal.StructureToPtr to get an unmanaged representation of the structure (which has to be a 'simple' structure). You might need to special case strings though.
You should also think about the alignment constraints on what you are searching for -- advancing through memory 1 byte at a time will be very slow and wasteful if the item must be 4 or 8 byte aligned.
In a program I'm working on, I need to write a function to take any numeric type (int, short, long etc) and shove it in to a byte array at a specific offset.
There exists a Bitconverter.GetBytes() method that takes the numeric type and returns it as a byte array, and this method only takes numeric types.
So far I have:
private void AddToByteArray<T>(byte[] destination, int offset, T toAdd) where T : struct
{
Buffer.BlockCopy(BitConverter.GetBytes(toAdd), 0, destination, offset, sizeof(toAdd));
}
So basically my goal is that, for example, a call to AddToByteArray(array, 3, (short)10) would take 10 and store it in the 4th slot of array. The explicit cast exists because I know exactly how many bytes I want it to take up. There are cases where I would want a number that is small enough to be a short to really take up 4 bytes. On the flip side, there are times when I want an int to be crunched down to just a single byte. I'm doing this to create a custom network packet, if that makes any ideas pop in to your heads.
If the where clause of a generic supported something like "where T : int || long || etc" I would be ok. (And no need to explain why they don't support that, the reason is fairly obvious)
Any help would be greatly appreciated!
Edit: I realize that I could just do a bunch of overloads, one for each type I want to support... but I'm asking this question because I want to avoid precisely that :)
I disagree that this can't be done; it's just that the design I'd propose to do it is a little weird (and involved).
Here's the idea.
The Idea
Define an interface IBytesProvider<T>, with one method:
public interface IBytesProvider<T>
{
byte[] GetBytes(T value);
}
Then implement this in a BytesProvider<T> class with a static Default property.
If this sounds familiar, it's because it's exactly how the EqualityComparer<T> and Comparer<T> classes work (heavily used in plenty of LINQ extension methods).
The Implementation
Here's how I'd propose you set it up.
public class BytesProvider<T> : IBytesProvider<T>
{
public static BytesProvider<T> Default
{
get { return DefaultBytesProviders.GetDefaultProvider<T>(); }
}
Func<T, byte[]> _conversion;
internal BytesProvider(Func<T, byte[]> conversion)
{
_conversion = conversion;
}
public byte[] GetBytes(T value)
{
return _conversion(value);
}
}
static class DefaultBytesProviders
{
static Dictionary<Type, object> _providers;
static DefaultBytesProviders()
{
// Here are a couple for illustration. Yes, I am suggesting that
// in reality you would add a BytesProvider<T> for each T
// supported by the BitConverter class.
_providers = new Dictionary<Type, object>
{
{ typeof(int), new BytesProvider<int>(BitConverter.GetBytes) },
{ typeof(long), new BytesProvider<long>(BitConverter.GetBytes) }
};
}
public static BytesProvider<T> GetDefaultProvider<T>()
{
return (BytesProvider<T>)_providers[typeof(T)];
}
}
The Payoff
Now, finally, once you'd done all this, what you'd do is simply call:
byte[] bytes = BytesProvider<T>.Default.GetBytes(toAdd);
No overloads needed.
You can do this by first seperating the method into two parts, one to turn the value into an array of bytes, and another to insert them. Then just use overloads:
public static void AddToByteArray(byte[] destination, int offset, long value)
{ InsertBytes(destination, offset, BitConverter.GetBytes(value)); }
public static void AddToByteArray(byte[] destination, int offset, int value)
{ InsertBytes(destination, offset, BitConverter.GetBytes(value)); }
public static void AddToByteArray(byte[] destination, int offset, short value)
{ InsertBytes(destination, offset, BitConverter.GetBytes(value)); }
private static void InsertBytes(byte[] destination, int offset, byte[] bytes)
{
Buffer.BlockCopy(bytes, 0, destination, offset, bytes.Length);
}
This would not work anyway, because which overload of BitConverter.GetBytes() to use is resolved at compile time and not at runtime, so the generic argument passed as T will not be used to help determine the GetBytes() overload. Since there is no overload that accepts object, this approach could not work even if you could constrain T around some specific set of types. So you are doubly-screwed here.
Your only real option here is to overload your AddToByteArray method for each numeric type you want to accept. I know you don't want to do that, but there's little else you can do. (You could accept an argument of object and use reflection to invoke the specific overload of GetBytes() based on the argument type, but that would be dog slow due to reflection and boxing overhead...)
As a simplification of Dan Tao's solution in combination with SLaks' suggestion, here's a complete generic BitConverter:
public class BitConverter<T>
{
public static readonly Func<T, byte[]> GetBytes = x => new byte[] { };
static BitConverter()
{
BitConverter<byte>.GetBytes = x => new byte[] { x };
BitConverter<bool>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<char>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<double>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<Int16>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<Int32>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<Int64>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<Single>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<UInt16>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<UInt32>.GetBytes = x => BitConverter.GetBytes(x);
BitConverter<UInt64>.GetBytes = x => BitConverter.GetBytes(x);
}
}
Your example would then look like this:
private void AddToByteArray<T>(byte[] destination, int offset, T toAdd) where T : struct
{
Buffer.BlockCopy(BitConverter<T>.GetBytes(toAdd), 0, destination, offset, sizeof(toAdd));
}
You would simply have to provide a GetBytes() method for each expected type to the static constructor. Which, by the way, is not limited to struct types, for example:
BitConverter<MemoryStream>.GetBytes = x => x.ToArray();
BitConverter<string>.GetBytes = x => Encoding.Default.GetBytes(x);
If there's no GetBytes() method for the generic type, it will return an empty array (but you might want to change the code to throw an Exception instead!).
This is a real problem in C#, there is no common interface that all numeric types implement, you can restrict to struct and new(), but that still will allow structs with a parameterless constructor. If you really want to restrict it, you sadly have to use defined overloads for all numeric types.
If you only care about running on little-endian systems (like Windows), you could add a constraint on IConvertible (which I believe all the numeric types support), use that to convert the value to a 64-bit integer, get the bytes for that, and then throw away the bytes you know you don't need. Something like this:
private byte[] NumberToBytes<T>(T value)
where T : new(), struct, IConvertible
{
var longValue = value.ToUInt64();
var bytes = BitConverter.GetBytes(longValue);
Array.Resize(ref bytes, sizeof(T));
return bytes;
}
Of course, this assumes that you're only working with integers -- it wouldn't work for float, double, or decimal. And as noted above, it would only work on little-endian systems; for big-endian, you would need to keep the last sizeof(T) elements from the array, not the first.