如何通过调用c#方法通过COM接口传递函数指针

本文关键字:COM 接口 传递函数 指针 何通过 调用 方法 | 更新日期: 2023-09-27 18:19:20

我有这个CLI c++代码调用方法WpfApplication1.NetLauncher。发射(IntPtr cb)通过反射:

#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
typedef int (__stdcall *PMyBeep)(); 
int __stdcall MyBeep()
{
return 123;
}
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
Assembly^ asmbl = Assembly::Load("WpfDemo");
    Type^ type = asmbl->GetType("WpfApplication1.NetLauncher");
Object^ obj = asmbl->CreateInstance("WpfApplication1.NetLauncher");
    MethodInfo^ method = type->GetMethod("Launch");
IntPtr pp=(IntPtr)MyBeep;
   Object^ magicValue = method->Invoke(obj, gcnew array<Object^>(1){pp});

    return 0;
}

和c#代码:

namespace WpfApplication1
{
public class NetLauncher
{
    delegate int Mydelegate();
    [System.STAThreadAttribute()]
    public int Launch( IntPtr dwData)
    //public int Launch(string path)
    {

        Mydelegate codeToRun = null;
        codeToRun = (Mydelegate)Marshal.GetDelegateForFunctionPointer(dwData,     typeof(Mydelegate));

        int res = codeToRun.Invoke();
      // ....
    }
  }
}

现在我尝试通过COM接口从Win32 c++调用此方法:

    //   ....
    CComPtr<IDispatch> disp = launcher.pdispVal;
DISPID dispid;
OLECHAR FAR* methodName = L"Launch";
hr = disp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    //   ?????  DWORD nData=(DWORD)MyBeep;
   //   ?????  CComVariant *func = new CComVariant(nData);

CComVariant FAR args[] = {*func};
DISPPARAMS noArgs = {args, NULL, 1, 0};
hr = disp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &noArgs, NULL, NULL, NULL); 

我想我必须将函数指针(MyBeep)保存为disparams中的CComVariant,但我不知道如何??

如何通过调用c#方法通过COM接口传递函数指针

我不在我的Windows电脑前…你能帮我试一下吗?

DISPPARAMS dispparams; 
memset(&dispparams, 0, sizeof dispparams);
dispparams.cNamedArgs = 0;
dispparams.cArgs = 1;
dispparams.rgvarg = new VARIANTARG[dispparams.cArgs];
dispparams.rgvarg[0].vt =  VT_I4;
dispparams.rgvarg[0].iVal =   reinterpret_cast<int>(MyBeep);