va_arg prevents me from calling a managed delegate

2019-08-01 20:47发布

In a C++/CLI assembly, I'm trying to call a managed delegate from a native callback. I followed Doc Brown's answer here, and my implementation so far looks like this:

The native callback - ignore the commented out parts for now:

static ssize_t idaapi idb_callback(void* user_data, int notification_code, va_list va)
{
    switch (notification_code)
    {
        case idb_event::byte_patched:
        {
            //ea_t address = va_arg(va, ea_t);
            //uint32 old_value = va_arg(va, uint32);
            return IdaEvents::BytePatched(0, 0);
        }
        break;
    }
    return 0;
}

As you can see above, I call this managed delegate instantiated in a static class:

public delegate int DatabaseBytePatchedHandler(int address, int originalValue);

private ref class IdaEvents
{
    static IdaEvents()
    {
        BytePatched = gcnew DatabaseBytePatchedHandler(&OnDatabaseBytePatched);
    }

    public: static DatabaseBytePatchedHandler^ BytePatched;

    private: static int OnDatabaseBytePatched(int address, int originalValue)
    {
        return 0;
    }
};

This compiles fine. But the code is incomplete - remember the commented out part in the native callback above? I actually have to retrieve the values from the va_list passed to the callback, and pass those on to my managed delegate:

            ea_t address = va_arg(va, ea_t);
            uint32 old_value = va_arg(va, uint32);
            return IdaEvents::BytePatched(address, old_value);

But as soon as I uncomment one of the lines using va_arg, I cannot compile the project anymore and retrieve the following errors marking the line where I call the managed delegate:

C3821   'IdaEvents': managed type or function cannot be used in an unmanaged function
C3821   'IdaEvents::BytePatched': managed type or function cannot be used in an unmanaged function
C3821   'BytePatched': managed type or function cannot be used in an unmanaged function
C3821   'DatabaseBytePatchedHandler::Invoke': managed type or function cannot be used in an unmanaged function
C3642   'int DatabaseBytePatchedHandler::Invoke(int,int)': cannot call a function with __clrcall calling convention from native code
C3175   'DatabaseBytePatchedHandler::Invoke': cannot call a method of a managed type from unmanaged function 'idb_callback'

This really confuses me. Why is the compiler suddenly acting up as soon as I try to use va_arg? Even a single line without any assignment causes this error to pop up.

Am I thinking too naive here? I'm obviously missing a piece of the puzzle, and any help supporting me in finding it is greatly appreciated.

0条回答
登录 后发表回答