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

发布于 2024-12-25 02:59:58 字数 1804 浏览 1 评论 0原文

我有这个 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();

      // ....
    }
  }
}

现在我尝试通过 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) 保存为 DISPPARAMS 中的 CComVariant,但我不知道如何???

I have this CLI c++ code for call method WpfApplication1.NetLauncher.Launch(IntPtr cb)
via reflection:

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

And c# code:

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

      // ....
    }
  }
}

Now I try to call this method from Win32 C++ via COM interfaces:

    //   ....

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

I think I have to save function pointer (MyBeep) as CComVariant in DISPPARAMS, but I don't know how???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南冥有猫 2025-01-01 02:59:58

我不在我的 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);

I'm not in front of my Windows machine... Can you try it for me?

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文