看板 C_Sharp 關於我們 聯絡資訊
最近在試廠商給的 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