最近在試廠商給的 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