作者toki (いまがその时だ)
看板C_Sharp
标题[心得] C# & C native call back
时间Fri Sep 10 12:42:37 2010
最近在试厂商给的 SDK,里面为了扩充性,很多函式可以传 function pointer 进去
并且让处理的结果利用 function pointer call back 回来告诉使用者
厂商给的 SDK 是 DLL,沟通的部分用 DllImport 就可以完成
但 callback 的部分则需要特别处理,多一层 delegate 去包装它
才能让 C code 再 callback 回 C# 的 code
以下 sample code 是以简单的 clib 里的 function qsort 来举例
qsort 是 clib 里面的一个让你不用死记 quick sort 怎麽写的 function
但它的原始宣告有点奇妙:
void qsort
(
void* base, // 要比的东西的 array
size_t num, // 总共有几个
size_t width, // 每一个多大
int(__cdecl*compare)(constvoid*elem1,constvoid*elem2)//比较用的func ptr
);
这个函数可以传任意型态的 array 进去,但是它都可以帮你执行 quick sort
关键在於 qsort 函式最後一个 parameter,它让使用者自己提供比大小的 function
所以你可以用这个 function 来排序任何变数型态的 array
以下直接贴 sample code,关键只有在於多一层 delegate 来处理 C 的 callback
另外因为只是简单范例,转型的部分直接先用 int 带过
--- start of program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace qsort_test
{
class Program
{
// 宣告一个 delegate 让 qsort 可以 callback 回来
delegate int CompareCallBack(ref int a, ref int b);
// 从 MSVCRT.DLL 里 import qsort() 的宣告
// 注意最後一个 func ptr parameter 被换成了对应的 delegate
[DllImport("MSVCRT.DLL")]
private static extern void qsort(
int[] objs, uint num, uint width, CompareCallBack compare);
// 实作符合 CompareCallBack delegate 的 function
static int CompareInt(ref int a, ref int b)
{
return a - b;
}
static void Main(string[] args)
{
Random r = new Random(Environment.TickCount);
int[] ary = new int[20];
Console.WriteLine("Values before qsort.");
for (int i = 0; i < ary.Length; i++)
{
ary[i] = r.Next();
Console.WriteLine("{0,12}", ary[i]);
}
Console.WriteLine("\nValues after qsort");
qsort(ary, 20, 4,
new CompareCallBack(CompareInt));
foreach (int i in ary)
{
Console.WriteLine("{0,12}", i);
}
Console.WriteLine("");
}
}
}
--- end of program.cs
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.113.72.1