声明:网络上类似的中文博客大有存在,本人知识水平有限,业余爱好,也是为了备份收藏How to make a callback to C# from C/C++ code

本着共享知识的初衷,翻译一份给大家参考,为了便于阅读不至于拗口,没有按照原文直译,不到之处或者翻译有误,还望勿喷,敬请指评。

几乎每个人都知道怎样调用一个非托管DLL中的函数,然而有时候我们希望能从C/C++代码中调用C#代码。
想象一个场景,其中有一个名为Engine.dll的本机C语言编写DLL的C#应用程序。在DLL中有一个名为“DoWork
的函数入口点,我需要对它进行调用。在Engine.dll中调用"DoWork"就像在C#代码中做以下声明一样简单。

[DllImport("Engine.dll")]
public static extern void DoWork(); 

这段代码运行将非常良好,然而,让我再假设一下DoWork是一个连续性运行的任务,为了保证我们的用户端可被更新,
我们希望显示一个进度。想要实现这一点,我们需要做出以下几步:

1.在C#代码中定义一个类似的非托管代码委托

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void ProgressCallback(int value);

2.在C代码中定义一个回调签名

typedef void (__stdcall * ProgressCallback)(int);

3.在C代码中更改DoWork的签名以便接收ProgressCallback的地址

DLL void DoWork(ProgressCallback progressCallback)

注意:DLL宏的声明是这样的

#define DLL __declspec(dllexport)

4.在C#代码中,我们需要创建一个非托管委托类型的委托

ProgressCallback callback =(value) =>{Console.WriteLine("Progress = {0}", value);};

5.然后为了调用DoWork,我们需要这样做

DoWork(callback);

这里有一个简单应用程序的示例源码.这个代码段包含其他代码套方案,其中有一个名为ProcessFile函数的C代码需要回调到C#,以便获得文件
路径进行用于进一步处理 - 当前情形下将打印文件的内容到控制台。

Engine.dll/Main.h

#include "Windows.h"#ifdef __cplusplus
extern "C"
{
#endif#define DLL __declspec(dllexport)typedef void (__stdcall * ProgressCallback)(int);typedef char* (__stdcall * GetFilePathCallback)(char* filter);DLL void DoWork(ProgressCallback progressCallback);DLL void ProcessFile(GetFilePathCallback getPath);#ifdef __cplusplus
}
#endif

Engine.dll/Main.c

#include "Main.h"
#include <stdio.h>DLL void DoWork(ProgressCallback progressCallback)
{int counter = 0;for(; counter<=100; counter++){// do the work...if (progressCallback){// send progress update
            progressCallback(counter);}}
}DLL void ProcessFile(GetFilePathCallback getPath)
{if (getPath){// get file path...char* path = getPath("Text Files|*.txt");// open the file for readingFILE *file = fopen(path, "r");// read bufferchar line[1024];// print file info to the screenprintf("File path: %s\n", path ? path : "N/A");printf("File content:\n");while(fgets(line, 1024, file) != NULL){printf("%s", line);}// close the file
        fclose(file);}
}

TestApp.exe/Program.cs

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;class Program
{[UnmanagedFunctionPointer(CallingConvention.StdCall)]delegate void ProgressCallback(int value);[UnmanagedFunctionPointer(CallingConvention.StdCall)]delegate string GetFilePathCallback(string filter);[DllImport("Engine.dll")]public static extern void DoWork([MarshalAs(UnmanagedType.FunctionPtr)] ProgressCallback callbackPointer);[DllImport("Engine.dll")]public static extern void ProcessFile([MarshalAs(UnmanagedType.FunctionPtr)] GetFilePathCallback callbackPointer);[STAThread]static void Main(string[] args){// define a progress callback delegateProgressCallback callback =(value) =>{Console.WriteLine("Progress = {0}", value);};Console.WriteLine("Press any key to run DoWork....");Console.ReadKey(true);// call DoWork in C code
        DoWork(callback);Console.WriteLine();Console.WriteLine("Press any key to run ProcessFile....");Console.ReadKey(true);// define a get file path callback delegateGetFilePathCallback getPath =(filter) =>{string path = default(string);OpenFileDialog ofd =new OpenFileDialog(){Filter = filter};if (ofd.ShowDialog() == DialogResult.OK){path = ofd.FileName;}return path;};// call ProcessFile in C code
        ProcessFile(getPath);}
}

以下附上本人编译的代码,和原文有点出入,主要是因为本人习惯用.NET 2.0,还有一些是为了编译期间顺利通过编译器。

代码使用Visual Studio 2010+VC6.0编写

下载地址:1.怎样从C_C++代码中对C#进行回调.rar

2.怎样从C_Cpp代码中对CSharp进行回调2.rar

转载于:https://www.cnblogs.com/passedbylove/p/6082220.html

[翻译]:怎样从C/C++代码中对C#进行回调相关推荐

  1. Venkat 演讲翻译:你要清除代码中的异味

    今天,Venkat Subramaniam 就关于清除代码异味的话题给我们做了一个非常有趣的演讲.下面就是我记录的一些他的话. 为什么我们需要有质量的代码? 敏捷开发方法是用来应付那些要求代码做大量改 ...

  2. python脚本实现将代码中的中文翻译为其他语言

    python脚本实现将代码中的中文翻译为其他语言 如果我们写的代码中带有中文的字符提示,现在要将其翻译成为其他国家的语言,在没有做多国语言配置的情况下只能自己手动复制翻译.这种机械重复性动作完全可以交 ...

  3. 测试nginx网站代码_在40行以下代码中使用NGINX进行A / B测试

    测试nginx网站代码 by Nitish Phanse 由Nitish Phanse 在40行以下代码中使用NGINX进行A / B测试 (A/B testing with NGINX in und ...

  4. 在Visual Studio代码中显示空白字符

    本文翻译自:Show whitespace characters in Visual Studio Code Is it possible to show whitespace characters, ...

  5. 如何从代码中获取当前方法的名称[复制]

    本文翻译自:How to get the name of the current method from code [duplicate] This question already has an a ...

  6. Visual Studio代码中的多个游标[关闭]

    本文翻译自:Multiple cursors in Visual Studio Code [closed] How can you create multiple cursors when editi ...

  7. redis高并发原理_Java中的42行代码中的URL缩短服务— Java(?!)Spring Boot + Redis...

    redis高并发原理 显然,编写URL缩短服务是新的"世界,您好! "在物联网/微服务/时代的世界中. 一切始于在45行Scala中的URL缩短服务-整洁的Scala,以Spray ...

  8. [翻译]在asp.net 2.0中使用WebParts

    原文地址:http://dotnetslackers.com/articles/aspnet/UsingWebPartsInASPNet20.aspx [译者改后代码下载] [翻译]在asp.net ...

  9. 【翻译】TCP backlog在Linux中的工作原理

    原文How TCP backlog works in Linux 水平有限,难免有错,欢迎指出! 以下为翻译: 当应用程序通过系统调用listen将一个套接字(socket)置为LISTEN状态时,需 ...

最新文章

  1. 找出重复最多的字符php,javascript获取重复次数最多的字符_javascript技巧
  2. html回车按键确认按钮,button默认enter事件(回车事件)。
  3. Linux提权:常用三种方法
  4. 【计算机网络复习】1.2.4 TCP/IP参考模型和5层参考模型
  5. css 文本溢出 0302
  6. 请概述可视化卷积神经网络的中间输出的基本思想。_万字长文:特征可视化技术(CAM)...
  7. 【毕业答辩】学位论文答辩ppt指南!
  8. dpf linux安装db2_值得一看!数据库及Mysql入门,附详细安装教程
  9. 山大824计算机基础,山东大学2020年考研824计算机基础考试大纲
  10. 虚拟机安装CentOS系统详细步骤。
  11. ffmpeg完全教程
  12. endnote x9打开闪退_Endnote X9 详细教程
  13. 【k8s系列001】K8s集群部署H2O
  14. 唐仲英基金会:从“钢铁大王”到“十大慈善家”,他的一生如此传奇
  15. 黑群晖折腾之百度网盘云同步
  16. iOS开发者账户密码修改流程
  17. exp/expdp 与 imp/impdp命令导入导出数据库详解
  18. 【PS】61款中国风古典背景水墨山水古风韵味PSD分层设计素材
  19. 统计分析——描述统计之数据水平描述
  20. 机器学习——经典降维算法与框架综述

热门文章

  1. Spring Cloud Sleuth进阶实战
  2. 特征点检测 FAST算法及代码详解
  3. Python 3.8.0a2 发布,面向对象编程语言
  4. 分享 : 警惕MySQL运维陷阱:基于MyCat的伪分布式架构
  5. amazeui学习笔记--css(基本样式3)--文字排版Typography
  6. VMware安装CentOS之二——最小化安装CentOS
  7. idea使用 git 撤销commit
  8. cmail服务器安装后无法登录的解决办法
  9. 团队项目计划BACKLOG
  10. [WCF安全系列]绑定、安全模式与客户端凭证类型:NetNamedPipeBinding、NetTcpBinding与NetMsmqBinding...