Search code examples
c#.netdllc++-climixed-mode

Calling overloaded C# array access from unmanaged C++/CLI


I have a C# project which has overridden the array access ([]) like so:

Foo.cs:

public override FooItem this[long index] {
    ...

The project is compiled into a .dll which is referenced by my C++/CLI project.

I have an unmanaged C++/CLI class, FooAccess:

FooAccess.h:

class FooAccess : NativeCPPClass { // not ref class
private:
    gcroot<CSDll::Foo^> myFoo;
public:
    void Accessor();

In FooAccess.cpp:

void FooAccess::Accessor() {
    myFoo->[0]; // doesn't work
    myFoo[0]; // doesn't work
    pin_ptr<FooItem^> p = &myFoo[0]; // doesn't work

I am stumped.

Note that I am not allowed to edit the C# project and the C++/CLI class cannot be a ref class since it inherits from a native class.


Solution

  • The gcroot template makes the syntax clumsy. You have to cast to convince it to spit out the object reference, ((Foo^)myFoo)[0]. Ugh. The readable way is to lift the object reference out of the template explicitly:

    void FooAccess::Accessor() {
        Foo^ obj = myFoo;
        FooItem^ value = obj[0];
        //...
    }
    

    But you can write it directly by using the default keyword:

    FooItem^ value = myFoo->default[0];
    

    Do consider encapsulation instead of inheritance, storing a private NativeCPPClass* in a ref class, helps you avoid the high cost and awkwardness of gcroot.