2

I would like to know if there is any way to create a generic pointer in C#. The problem is quite similar to Pointers of generic type?, I can however not see any way to make any of the solutions work in my case. Although it helped explain why limiting the generic type to be a value type wasn't enough, Why is pointer to generic types not allowed?, did also not help as creating overloads for every possible type, while possible, is not desired here.

Thus the problem setting is basically that there is some generic function that needs to cast a void* to a specific type of pointer, example function see below:

public static unsafe T[] fooBar<T>(void* ptr, int length) where T : struct
{
    T* typedPointer = (T*) ptr; // This does not appear to be possible in this form
    T[] retVal = new T[length];

    for (int i = 0; i < length; i++) {
        T[i] = *typedPointer;
        ++typedPointer;
    }

    return retVal;
}

The reason that the use of pointers is necessary here is due to some unmanaged code with C-style exports being called, which returns a System.Reflection.Pointer, which is then turned into a void* via Pointer.Unbox().

Is there any way at all to cast void* to T* as seen above, or is the use of a generic type pointer impossible?

abcalphabet
  • 1,158
  • 3
  • 16
  • 31
  • [This answer](https://stackoverflow.com/a/42940147/20047) expains your problem: a generic type constrained to struct may still have fields with reference types (e.g. string). – jeroenh Aug 15 '18 at 14:36
  • Possible duplicate of [Why is pointer to generic types not allowed?](https://stackoverflow.com/questions/42940040/why-is-pointer-to-generic-types-not-allowed) – jeroenh Aug 15 '18 at 14:40
  • @jeroenh That's why I referenced it in the first paragraph :) While it does explain why restricting the generic to be a value type doesn't work I was just wondering if there is some way to make generic type pointers work – abcalphabet Aug 15 '18 at 14:43
  • you're out of luck, I'm afraid... See also JaredPar's answer to [this question](https://stackoverflow.com/questions/1579559/marshalling-net-generic-types): 'generics, as a rule, are not supported in any interop scenario'... – jeroenh Aug 15 '18 at 14:50
  • Ah, I see, that's unfortunate... But thanks for digging up the post! – abcalphabet Aug 15 '18 at 14:57
  • 1
    You don't need the ability to cast pointers here, as you're copying structs into an array. `Marshal.PtrToStructure` will do, on a `byte*` that you increment with `Marshal.SizeOf()`. – Jeroen Mostert Aug 16 '18 at 10:20
  • [See also](https://stackoverflow.com/q/6747112/4137916). Should marshalling the arrays this way prove too much overhead, a C++/CLI wrapper to produce them directly should help. That also allows you to get rid of the `Reflection.Pointer` business. – Jeroen Mostert Aug 16 '18 at 10:26
  • @Jeroen Mostert Using `Marshal.PtrToStructure` and `Marshal.SizeOf` did the trick for me, thanks a lot! – abcalphabet Aug 16 '18 at 12:46

0 Answers0