3

I am trying to write a managed wrapper class in order to perform interop and conversion for a native class. I wrote something similar to this in my interop library;

namespace MyNamespace {
    public ref class MyClass {
    public:
        static void MyMethod(double myArray[]);
    }
}

However when I reference this library from my C# application, the interface has changed. If I F12 on the class in C# I get the regenerated interface MyClass [from metadata] which looks like this;

namespace MyNamespace {
    public class MyClass {
        public static void MyMethod(double myArray*);
    }
}

Why did the compiler convert the array into a pointer? How can I get the compiler to correctly expose this argument as an array rather than a pointer?

If I want to use the class in this way then I would have to get a pointer to the managed array in an unsafe context, which I don't want to do.

Update

When I do typeof(double[]) in C# I get;

{Name = "Double[]" FullName = "System.Double[]"}
    Assembly: {mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
    AssemblyQualifiedName: "System.Double[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    Attributes: Public | Sealed | Serializable
    BaseType: {Name = "Array" FullName = "System.Array"}
    ...}

So I understand the comments suggesting that I need a System.Array. However, my question still stands, how do I declare a System.Double[] array in the interop class? Simply putting MyMethod(System::Double[] myArray) doesn't work...

4
  • I could be wrong, but I believe I am correct. It's converted to a pointer, because the array in your C++ doesn't utilize System.Array for arrays, which C# does and in that case it just expects a pointer to the data instead. Commented Jan 3, 2017 at 12:13
  • If so, maybe you could replace the double[] argument by some .net array type. It should be possible to use such a type in C++/CLI Commented Jan 3, 2017 at 12:17
  • My problem is that System.Array is typeless. I want the argument to be interpreted as a double[] not a System.Array. Commented Jan 3, 2017 at 12:18
  • I understand that in the native world, arrays and pointers are synonymous. However, there is such thing as a managed double[] and it can be passed in an argument, so how do I get the ref class to expose it as a double [] instead of a double*? Commented Jan 3, 2017 at 12:25

1 Answer 1

6

Use cli::array<double>^ which is a managed array. The double something[] syntax will define an unmanaged array, which decays to a pointer in metadata.

See here for reference.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you Lucas, that is more like what I am looking for. However, I tried replacing it and I get the message "a C++/CLI array type is not allowed here". It allows std::array but I don't thin that is what I am looking for...
I tried using std::array. I have to specify the rank, such as array<double, 1>. This still doesn't work as I get a different error "incomplete type is not allowed".
@Steztric Are you sure you didn't omit the final ^? You may also try to drop the cli::. Unfortunately I don't have a compiler handy at the moment so I can't check myself. std::array is something entirely different, you can't use that from C#.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.