首页 > 其他分享 >P/Invoke 回调示例

P/Invoke 回调示例

时间:2023-08-28 10:45:44浏览次数:36  
标签:Invoke 示例 ByVal value Public LibWrap 回调 public

回调示例

 

在本文中

  1. 声明原型
  2. 调用函数

此示例演示如何将委托传递给需要函数指针的非托管函数。委托是一个可以保存方法引用的类,相当于类型安全的函数指针或回调函数。Microsoft .NET Framework SDK 包含此示例的完整 Visual Basic .NET 和 C# 版本,位于 Samples\Technologies\Interop\Platform-Invoke 中。

注意   当您在调用中使用委托时,公共语言运行时会保护委托在该调用期间不被垃圾回收。但是,如果非托管函数存储委托以在调用完成后使用,则必须手动阻止垃圾回收,直到非托管函数完成委托。有关更多信息,请参阅HandleRef 示例GCHandle 示例

回调示例使用以下非托管函数,并显示其原始函数声明:

  • 从 PinvokeLib.dll 导出的TestCallBack。

    void TestCallBack(FPTR pf, int value);
    
  • 从 PinvokeLib.dll 导出的TestCallBack2。

    void TestCallBack2(FPTR2 pf2, char* value);
    

PinvokeLib.dll是一个自定义非托管库,其中包含前面列出的函数的实现。

在此示例中,该类包含和方法LibWrap的托管原型。这两种方法都将委托作为参数传递给回调函数。委托的签名必须与其引用的方法的签名相匹配。例如,和委托具有与和方法相同的签名。TestCallBackTestCallBack2FPtrFPtr2DoSomethingDoSomething2

声明原型

VB
Public Delegate Function FPtr( ByVal value As Integer ) As Boolean
Public Delegate Function FPtr2( ByVal value As String ) As Boolean

Public Class LibWrap
   ' Declares managed prototypes for unmanaged functions.
   Declare Sub TestCallBack Lib "..\LIB\PinvokeLib.dll" ( ByVal cb _
      As FPtr, ByVal value As Integer )
   Declare Sub TestCallBack2 Lib "..\LIB\PinvokeLib.dll" ( ByVal cb2 _
      As FPtr2, ByVal value As String )
End Class 'LibWrap
[C#]
public delegate bool FPtr( int value );
public delegate bool FPtr2( String value );

public class LibWrap
{// Declares managed prototypes for unmanaged functions.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern void TestCallBack( FPtr cb, int value );   
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern void TestCallBack2( FPtr2 cb2, String value );   
}

调用函数

VB
Public Class App
   Public Shared Sub Main()

      Dim cb As FPtr
      cb = AddressOf App.DoSomething
      Dim cb2 As FPtr2
      cb2 = AddressOf App.DoSomething2
      LibWrap.TestCallBack( cb, 99 )
      LibWrap.TestCallBack2( cb2, "abc" )
   End Sub 'Main
   Public Shared Function DoSomething( ByVal value As Integer ) As Boolean
      Console.WriteLine( ControlChars.CrLf + "Callback called with _
         param: {0}", value )
      ...
   End Function 'DoSomething
   Public Shared Function DoSomething2( ByVal value As String ) As Boolean
      Console.WriteLine( ControlChars.CrLf + "Callback called with _
          param: {0}", value )
      ...
   End Function 'DoSomething2
End Class 'App
[C#]
public class App
{
   public static void Main()
   {
      FPtr cb = new FPtr( App.DoSomething );
      LibWrap.TestCallBack( cb, 99 );
      FPtr2 cb2 = new FPtr2( App.DoSomething2 );
      LibWrap.TestCallBack2( cb2, "abc" );
   }
   
   public static bool DoSomething( int value )
   {
      Console.WriteLine( "\nCallback called with param: {0}", value );
      ...
   }
   public static bool DoSomething2( String value )
   {
      Console.WriteLine( "\nCallback called with param: {0}", value );
      ...
   }   
}

也可以看看

杂项编组样本平台调用数据类型在托管代码中创建原型

 

标签:Invoke,示例,ByVal,value,Public,LibWrap,回调,public
From: https://www.cnblogs.com/ioriwellings/p/17661648.html

相关文章

  • mysql学习-生产配置文件示例以及分区配置
    生产上mysql配置文件my.cnf[mysqld]#default-character-set=utf8basedir=/data/mysqldatadir=/data/mysql/data#skip-grant-tableslower_case_table_names=1socket=/tmp/mysql.sockport=3306server-id=2innodb_flush_log_at_trx_commit=0innodb_autoextend_increment=128......
  • linux学习-nginix生产配置示例
    usernginxnginx;worker_processes8;worker_rlimit_nofile65535;error_log/var/log/nginx/error.logerror;pidlogs/nginx.pid;events{ useepoll;worker_connections65535; multi_accepton;}http{includemime.types;......
  • torch索引使用方式示例
    已知b=torch.Tensor([[1],[2]]),请问b[1]和b[[1]]的区别在PyTorch中,b[1] 和 b[[1]] 之间有一个微妙的区别,这涉及到张量的索引和切片操作。让我解释一下两者之间的区别:b[1]:这是使用整数索引来获取张量 b 中的元素。由于 b 是一个形状为(2,1)的张量,使用整数索......
  • Python+Requests示例记录【2023-08-27】
    importrequestsimportjsonpayload={"userNo":"用户","password":"密码"}response=requests.post(url,json=payload)print(response)print('---------------------------')print(response.status_code)print('......
  • 装饰器示例
    1.装饰器语法糖示例注解形式:#1定义一个装饰器(装饰器的本质是闭包)defcheck(fn):definner():print("请先登陆")fn()returninner#2使用装饰器装饰函数(增加一个登陆功能)#解释器遇到@check会立即执行comment=check(comment)@check......
  • 一个简单的spdlog使用示例
    目录引用源码封装Log头文件使用方法spdlog是一个开源、跨平台、无依赖、只有头文件的C++11日志库,网上介绍的文章有很多这里就不过多的介绍了,GitHub链接:https://github.com/gabime/spdlog。引用源码先下载spdlog的源码,将源码的include文件夹复制到自己的项目文件夹下:然后在项......
  • 【算法-二分查找】实现过程、C++代码示例以及实际应用
    二分查找简介:也称为折半查找,是一个在已排序数组中查找特定元素的搜索算法。它的工作原理是将有序数组分成两半,然后检查目标值是在左半部分还是右半部分,然后在所选择的那部分中继续查找。这一过程将不断地重复,直到找到目标值或确定目标值不在数组中。实现过程:1.初始化两个指针:lo......
  • [远程Call]32位远程多参数带返回调用
    [远程Call]32位远程多参数带返回调用引子在Windows上可以使用CreateRemoteThread实现远程Call,但是有不带返回值且只能传递一个参数的限制。解决思路将多个参数利用VirtualAllocEx和WriteProcessMemory写入目标程序,再通过此方法注入一段shellcode,通过shellcode完成多参数的......
  • linux docker公网源下载示例
    1.get-docker.sh百度一下,进入docker官网直接下载该文件,然后执行即可2.直接下载repo文件示例:wgethttps://download.docker.com/linux/centos/docker-ce.repo-O/etc/yum.repos.d/docker.sh--no-check或者yum-config-manager--add-repohttps://download.docker.com/lin......
  • Angular:表单设置动态校验规则(ngZorro示例)
    背景有时我们需要根据不同的条件,决定表单控件是否是必填的。代码示例HTML文件<formnz-form[formGroup]="validateForm"(ngSubmit)="submitForm()"><nz-form-item><nz-form-label[nzSpan]="4"nzRequirednzFor="name">Name</nz-f......