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

时间:2012-01-04 14:11:26

标签: c# c++ reflection com c++-cli

我有调用方法WpfApplication1.NetLauncher.Launch(IntPtr cb)的CLI c ++代码 通过反思:

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

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

1 个答案:

答案 0 :(得分:0)

我不在我的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);
相关问题