c ++/cli передача (управляемый) делегат в неуправляемом коде

Как я передаю указатель функции от управляемого С++ (C++ / CLI) к неуправляемому методу? Я прочитал несколько статей, как этот из MSDN, но он описывает два различных блока, в то время как я хочу только один.

Вот мой код:

1) Заголовок (MyInterop. ManagedCppLib.h):

#pragma once

using namespace System;

namespace MyInterop { namespace ManagedCppLib {

    public ref class MyManagedClass
    {
    public:
        void DoSomething();
    };
}}

2) Код CPP (MyInterop. ManagedCppLib.cpp)

#include "stdafx.h"
#include "MyInterop.ManagedCppLib.h"

#pragma unmanaged
void UnmanagedMethod(int a, int b, void (*sum)(const int))
{
    int result = a + b;
    sum(result);
}

#pragma managed
void MyInterop::ManagedCppLib::MyManagedClass::DoSomething()
{
    System::Console::WriteLine("hello from managed C++");
    UnmanagedMethod(3, 7, /* ANY IDEA??? */);
}

Я пытался создать своего управляемого делегата, и затем я пытался использовать Marshal::GetFunctionPointerForDelegate метод, но я не мог скомпилировать.

26
задан Deduplicator 9 March 2015 в 20:55
поделиться

1 ответ

Да, вам нужен Marshal::GetFunctionPointerForDelegate(). В вашем фрагменте кода отсутствует управляемая функция, которую вы хотите вызвать, я просто придумал ее. Вам также придется объявить тип управляемого делегата и создать его экземпляр, прежде чем вы сможете получить указатель функции. Это сработало хорошо:

#include "stdafx.h"

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed(push, off)
typedef void (* UnmanagedSummer)(int arg);

void UnmanagedMethod(int a, int b, UnmanagedSummer sum)
{
    int result = a + b;
    sum(result);
}
#pragma managed(pop)

ref class Test {
    delegate void ManagedSummer(int arg);
public:
    static void Run() {
        Test^ t = gcnew Test();
        ManagedSummer^ managed = gcnew ManagedSummer(t, &Sum);
        IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(managed);
        UnmanagedSummer functionPointer = static_cast<UnmanagedSummer>(stubPointer.ToPointer());
        UnmanagedMethod(1, 2, functionPointer);
        GC::KeepAlive(managed);    // Important: ensure stub can't be collected while native code is running
        System::Diagnostics::Debug::Assert(t->summed == 3);
    }
    void Sum(int arg) {
        summed += arg;
    }
    int summed;
};

int main(array<System::String ^> ^args)
{
    Test::Run();
    return 0;
}
42
ответ дан 28 November 2019 в 07:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: