Как передать указатель на функцию при вызове метода C # через COM-интерфейсы - PullRequest
1 голос
/ 04 января 2012

У меня есть этот код CLI c ++ для вызова метода WpfApplication1.NetLauncher.Launch (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();

      // ....
    }
  }
}

Теперь я пытаюсь вызвать этот метод из Win32 C ++ через COM-интерфейсы:

    //   ....

    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) как CComVariant в DISPPARAMS, но я не знаю, как ???

1 Ответ

0 голосов
/ 04 января 2012

Я не перед моей машиной с 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);
...