c ++ / cli传递(托管)委托给非托管代码 [英] c++/cli pass (managed) delegate to unmanaged code

查看:254
本文介绍了c ++ / cli传递(托管)委托给非托管代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将函数指针从托管C ++(C ++ / CLI)传递到非托管方法?我阅读了几篇文章,例如 MSDN中的此,但它描述了两个不同的程序集,而



1)头文件(MyInterop.ManagedCppLib.h)

  #pragma once 

使用命名空间System;

命名空间MyInterop {namespace ManagedCppLib {

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

2)CPP代码(MyInterop.ManagedCppLib.cpp)

  #includestdafx.h
#includeMyInterop.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 方法,但我无法编译。

解决方案

想要Marshal :: GetFunctionPointerForDelegate()。您的代码段缺少您想要调用的托管函数,我刚刚创建了一个。您还必须声明托管委托类型并创建它的实例,然后才能获取函数指针。这很好:

  #includestdafx.h

使用命名空间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);
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;
}


How do I pass a function pointer from managed C++ (C++/CLI) to an unmanaged method? I read a few articles, like this one from MSDN, but it describes two different assemblies, while I want only one.

Here is my code:

1) Header (MyInterop.ManagedCppLib.h):

#pragma once

using namespace System;

namespace MyInterop { namespace ManagedCppLib {

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

2) CPP Code (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??? */);
}

I tried creating my managed delegate and then I tried to use Marshal::GetFunctionPointerForDelegate method, but I couldn't compile.

解决方案

Yes, you want Marshal::GetFunctionPointerForDelegate(). Your code snippet is missing the managed function you'd want to call, I just made one up. You will also have to declare the managed delegate type and create an instance of it before you can get a function pointer. This worked well:

#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);
        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;
}

这篇关于c ++ / cli传递(托管)委托给非托管代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆