C++/CLI Why do I have to dereference a ref class type to invoke a managed method in native code but not when invoking overloaded operators?

Viewed 52

Unmanaged (C++ DLL):

template<typename T>
inline void native_template(T t) 
{
    // Not dereferenced?...
    t("This is a native template function. Printed as functor.");

    // Dereference necessary, will throw C2228 without it
    (*t).Print("This is a native template function. Printed via direct method invocation.");
}

// This is why I'm asking the question
// It can't accommodate internal use within the native dll
struct Temp
{
    void operator()(const char* str) { std::cout << str << std::endl; }
    void Print(const char* str) { std::cout << str << std::endl; }
};

inline void temp_invoke() {
    Temp t;

    //neither case compiles, obviously
    //native_template(&t); // C2100
    //native_template(t); // C2064
}

Managed (C++/CLI DLL):


public ref struct IManaged abstract
{
    virtual void operator()(System::String^) = 0;
    virtual void Print(System::String^) = 0;
};

public ref struct Wrapper
{
    static void Invoke(IManaged^ f) 
    {
        native_template(f);
    }
}

C# DLL:

public class Managed : IManaged
{
    public override void op_FunctionCall(string str) {
        Console.WriteLine(str);
    }

    public override void Print(string str) {
        Console.WriteLine(str);
    }
}

main:
Wrapper.Invoke(new Managed);

This doesn't make much sense to me. Why do I have to dereference to invoke other methods but not for overloaded operators i.e. functors?

EDIT

I have 3 projects in Visual Studio outputting 3 dlls, one in pure native code (no CLR support), one c++/cli, and one c# application. The native code is linked to c++/cli, and it in turn is referenced in the c# project. They all output their binaries to the exact same folder. The compiler is MSVC++ 14.30 (_MSC_VER 1933). I appended the C# script for clarification.

My original question was not arbitrary. The method in the native c++ section can possibly be used internally, taking either a native ptr type or an instance. Neither case can be compiled, which means I possibly have to make another method to do the same thing for internal c++ usage. I clarified that in the example.

Meanwhile the code above runs just fine without notable errors, as long as I play along with the weird syntax. I'm wondering now if this is not a common feature or an expected behavior in c++/cli. I did not expect this question to be confusing at all or resulting in completely different outcomes in different platforms/environment.

0 Answers
Related