使用 SWIG 从 C++ 回调到 C#

2023-11-29

我有一个在 C#.Net Core 和 C++ Windows 应用程序中运行的应用程序。
我使用 SWIG 实现了 C# 和 C++ 之间的互操作性。

但我无法实现从 C++ 到 C# 的回调功能。我还尝试将函数指针从 C# 传递到 C++。但也失败了

我的意图是通过以下方式实现回调

  1. 通过将 C# 函数指针传递给 C++,并在需要时调用该函数指针,以便执行 C# 函数。

  2. 在 C++ 中创建带有虚函数的基类,并在 C# 中派生一个实现虚方法的类。将导出的对象设置为 C++,以便我可以调用对象->虚拟方法将调用 C# 函数。

但这两种方法都失败了。

''' C++ Code

    #pragma once
    #include <string>
    #include "TestDataClass.h"

    using namespace std;

    class EventHandlerBase
    {
    public:

        virtual void handle() = 0;

    };

    class TestClass
    {
    public:
        TestClass();
        ~TestClass();

        TestDataClass oData;
        TestDataClass* pData;

        int times2(int arg, string data);
        void SetData(TestDataClass data);
        void SetPointerData(TestDataClass* data);
        TestDataClass* GetPointerData();
        TestDataClass GetData();
        void Print();



        EventHandlerBase* EventObject;
        void SetEventObj(EventHandlerBase* data);


    };

'''

'''C++ 实现

#include "TestClass.h"
#include <iostream>

TestClass::TestClass()
{

}

TestClass::~TestClass()
{
}

int TestClass::times2(int arg, string data)
{
    return arg * 2;
}

void TestClass::SetData(TestDataClass data)
{
    this->oData = data;
}

void TestClass::SetPointerData(TestDataClass* data)
{
    this->pData = data;
}


void TestClass::Print()
{
    cout << this->oData.iData << endl;
    cout << this->oData.sData << endl;

    cout << this->pData->iData << endl;
    cout << this->pData->sData << endl;
    this->EventObject->handle();
}

TestDataClass* TestClass::GetPointerData()
{
    return this->pData;
}

TestDataClass TestClass::GetData()
{
    return this->oData;
}

void TestClass::SetEventObj(EventHandlerBase* data)
{
    if (data)
    {
        this->EventObject = data;
    }
    else
    {
        cout << "Event object is null" << endl;
    }
}

'''

''' 接口代码

%module CppTestApp

 %include <windows.i>
 %include <std_string.i>

 // generate directors for all classes that have virtual methods
%feature("director") EventHandlerBase; 

%{
    #include "TestClass.h"
    #include "TestDataClass.h"
%}


%include "TestClass.h"
%include "TestDataClass.h"

'''

'''C# Code

 class MyEventHandler : EventHandlerBase
    {
        public MyEventHandler() : base(System.IntPtr.Zero, false) { }
        public override void handle()
        {
            System.Console.WriteLine("handling event...");
        }
    }

 static void Main(string[] args)
        {
            TestClass cpp_File = new TestClass();

            MyEventHandler myEvent = new MyEventHandler();

            TestDataClass data = new TestDataClass() { iData = 10, sData = "Hello I am Object" };
            TestDataClass pData = new TestDataClass() { iData = 25, sData = "Hello I am Pointer" };

            Console.WriteLine(cpp_File.times2(1, "Haii").ToString());

            cpp_File.SetData(data);
            cpp_File.SetPointerData(pData);

            Console.WriteLine($"{cpp_File.GetData().iData}  ,  {cpp_File.GetData().sData}");
            Console.WriteLine($"{cpp_File.GetPointerData().iData}  ,  {cpp_File.GetPointerData().sData}");

            cpp_File.SetEventObj(myEvent);

            cpp_File.Print();


            Console.WriteLine("-----------------------------");
            Console.ReadLine();
        }

'''

当我执行时cpp_File.SetEventObj(myEvent);Cpp 的对象设置为空。所以我无法调用虚函数。

你能帮我吗?

另外,如果这不是正确的方法,请建议一些方法实现从C++到C#的回调(使用SWIG)或任何其他方法设置从 C# 到 C++ 的函数指针(使用 SWIG).

这样我就可以设置一个从C#到C++的函数指针,并通过调用该函数指针来实现对C#的回调


我得到了上述查询的答案,并将其发布在这里。 您还可以参考this Link

更改如下 SWIG 接口代码后,它对我有用

'''接口代码

%module (directors="1") CppTestApp


%{
    #include "TestClass.h"

    #include "TestDataClass.h"
%}


 %include <windows.i>
 %include <std_string.i>

%feature("director") EventHandlerBase;

%include "TestClass.h"
%include "TestDataClass.h"

'''

'''C# Code

class MyEventHandler : EventHandlerBase
    {

        public override void handle()
        {
            System.Console.WriteLine("handling event...");
        }
    }

'''

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 SWIG 从 C++ 回调到 C# 的相关文章

  • 将完整模板参数值映射到原始类型

    我想将数字映射到类型 在这个例子中 我将创建一个函数 将 sizeof 结果映射到有符号的原始类型 我想知道是否有更好的方法来完成我在现代 C 中所做的事情 即采用模板化值并将其转换为类型 现在 这可以将大小转换为已知类型 但我似乎无法在标
  • linq 中使用字符串数组 c# 的 'orderby'

    假设我有一个这样的方法定义 public CustomerOrderData GetCustomerOrderData string CustomerIDs var query from a in db Customer join b in
  • std::call_once 可重入且线程安全吗?

    std call once http en cppreference com w cpp thread call once是线程安全的 但它也是可重入的吗 我使用 VS2012 调试和发布 进行的测试表明 调用std call once从单
  • 是否存在指向不同类型的指针具有不同大小的平台?

    C 标准允许指向不同类型的指针具有不同的大小 例如sizeof char sizeof int 是允许的 但是 它确实要求如果将指针转换为void 然后转换回其原始类型 它必须与其原始值进行比较 因此 从逻辑上来说 sizeof void
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • 将表(行)与 OpenXML SDK 2.5 保持在一起

    我想在 Word 文档中生成多个表 每行 2 行 但我想将这两行保留在一起 如果可能的话 new KeepNext 第一行不起作用 new KeepNext 第一行的最后一段不起作用 new CantSplit 放在桌子上不起作用 在所有情
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • 使用 C# 和 wpf 创建类似 Dock 的应用程序

    我需要创建一个与我们购买笔记本电脑时获得的应用程序类似的应用程序 仅当鼠标指针到达窗口顶部时它才可见 那么我怎样才能使用 C 4 0 来做到这一点呢 http www notebookcheck net uploads pics win2
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • C#6 中的长字符串插值行

    我发现 虽然字符串插值在应用于现有代码库的字符串 Format 调用时非常好 但考虑到通常首选的列限制 字符串对于单行来说很快就会变得太长 特别是当被插值的表达式很复杂时 使用格式字符串 您将获得一个可以拆分为多行的变量列表 var str
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 逆向工程 ASP.NET Web 应用程序

    我有一个 ASP NET Web 应用程序 我没有源代码 该 bin 包含 10 个程序集和一个 compiled 文件 我在 App Code dll 上使用 Reflector 它向我显示了类和命名空间之类的东西 但它太混乱了 有没有什
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • 为什么以下 C 程序会出现总线错误?

    我认为这是第一个失败的 strtok 调用 好久没写C了 有点不知所措 非常感谢 include
  • 来自 3rd 方库的链接器错误 LNK2019

    我正在将旧的 vc 6 0 应用程序移植到 vs2005 我收到以下链接器错误 我花了几天时间试图找到解决方案 错误LNK2019 无法解析的外部符号 imp 创建AwnService 52 在函数 public int thiscall
  • 使用未分配的局部变量

    我遇到了一个错误 尽管声明了变量 failturetext 和 userName 错误仍然出现 谁能帮帮我吗 Use of Unassigned local variable FailureText Use of Unassigned lo

随机推荐