arcsoft.com.cn/ai/arcfa
ce.html
動態呼叫(p/invoke)
我們可以將c或者c++的函式封裝成com元件,在c#中呼叫時比較方便,但是com元件需要註冊,而且多次註冊可能也會導致一些問題,同時在處理c或者c++的型別與com元件的型別轉換的時候也可能有些麻煩
採用動態的方式就是直接用c#呼叫c或者c++已經寫好的動態鏈結庫,這幾種方式相對而言,p/invoke要方便一些
p/invoke的全稱是platform invoke (平台呼叫) 它實際上是一種函式呼叫機制,通過p/invoke我們就可以呼叫非託管dll中的函式 ,實際上很多net基類庫中定義的類 型內部部呼叫了從kernel32.dll,user32.dll,gdi32.dll等非託管dll中匯出的函式。
來看乙個簡單的例子
[dllimportattribute("user32.dll", entrypoint = "setcursorpos")] [return: marshalasattribute(unmanagedtype.bool)] //可寫可不寫,定義如何封送返回引數 public static extern bool setcursorpos(int x, int y);
這段**的目的就是呼叫系統中獲取滑鼠引數的方法。
p/invoke的過程
關於p/invoke的過程,我找到了msdn上的一張圖,如下所示。
1 查詢包含該函式的非託管dll
2 將該非託管dll載入到記憶體中
3 查詢函式在記憶體中的位址並將其引數按照函式的呼叫約定壓棧
4 將控制權轉移給非託管函式
看起來很複雜,但使用起來卻很簡單,只需要在c#中重新宣告函式的定義就可以了,然後可以像其它函式一樣呼叫。
看起來很複雜,但使用起來卻很簡單,只需要在c#中重新宣告函式的定義就可以了,然後可以像其它函式一樣呼叫。
arcsoft.com.cn/ai/arcfa
ce.html
typedef mint32 afd_fsdk_orientcode;
mrect * rcface;
mlong nface;
afd_fsdk_orientcode * lfaceorient;
} afd_fsdk_faceres, * lpafd_fsdk_faceres;
intptr用於表示指標或控制代碼的平台特定型別。這個其實說出了這樣兩個事實,intptr 可以用來表示指標或控制代碼、它是乙個平台特定型別,它主要用在兩個地方:
(1)c#呼叫win32 api時
(2)c#呼叫c/c++寫的dll時(其實和1相同,只是這個一般是我們在和他人合作開發時經常用到)
我們可以這樣子理解,intptr就可以互換c++中的指標
); sdkkey [in] 使用者申請sdk時獲取的sdk key
pmem [in] 分配給引擎使用的記憶體位址
lmemsize [in] 分配給引擎使用的記憶體大小
pengine [out] 引擎handle
iorientpriority [in] 期望的臉部檢測角度範圍
nscale [in] 用於數值表示的最小人臉尺寸 有效值範圍[2,50] 推薦值 16。該尺寸是人臉相對於所在的長邊的佔比。例如,如果使用者想檢測到的最小人臉尺寸是長度的1/8,那麼這個nscale就應該設定為8
nmaxfacenum [in] 使用者期望引擎最多能檢測出的人臉數 有效值範圍[1,50]
cdecl 呼叫方清理堆疊。這使您能夠呼叫具有 varargs 的函式(如 printf),使之可用於接受可變數目的引數的方法。
fastcall 不支援此呼叫約定。
stdcall 被呼叫方清理堆疊。這是使用平台 invoke 呼叫非託管函式的預設約定。
thiscall 第乙個引數是 this 指標,它儲存在暫存器 ecx 中。其他引數被推送到堆疊上。此呼叫約定用於對從非託管 dll 匯出的類呼叫方法。
winapi 此成員實際上不是呼叫約定,而是使用了預設平台呼叫約定。例如,在 windows 上預設為 stdcall,在 windows
上預設為 cdecl。
預設情況下,c和c++使用的cdecl呼叫,因此我們在呼叫dll時指定這個值就可以。
marshal類提供了乙個方法集合,這些方法用於分配非託管記憶體、複製非託管記憶體塊、將託管型別轉換為非託管型別,此外還提供了在與非託管**互動時使用的其他雜項方法,我們將會在下面開發程序中頻繁使用這個類的多個方法。
例如:在定義乙個指標型別變數時intptr,我們需要使用marshal.allochglobal為其分配記憶體,得到intptr變數,在分配記憶體時,我們需要使用marshal.sizeof計算需要分配的記憶體的大小。然後呼叫marshal.
structuretoptr為變數賦值
int nscale = 50;
int nmaxfacenum = 10;
string sdkfdkey = "你申請到的fdkey";
if (retcode != 0)
openfile.filter = "檔案|*.bmp;*.jpg;*.jpeg;*.png|所有檔案|*.*;";
引擎初始化失敗
找不到dll
首先請保證你把dll拷貝到對應的目錄下面,其次要確定設定輸出選項為拷貝到輸出目錄。
記憶體不能讀或者寫
這個是c++的尿性,也是c#程式設計師不多見的報錯,主要檢查相關引數是否傳入正確。還要注意,如果人臉檢測返回的值不為0,獲取到的人臉數目會是乙個比較大的隨機數。這個時候如果用迴圈讀取,就會出現位址越界的情況。
虹軟人臉識別Android Sample Code
afr fsdkinte ce engine new afr fsdkengine 用來存放提取到的人臉資訊,face 1 是註冊的人臉,face 2 是要識別的人臉 afr fsdkface face1 new afr fsdkface afr fsdkface face2 new afr fsd...
虹軟人臉識別C demo
同理新增附加庫目錄,如下圖所示 附加依賴項 將兩個dll複製到程式執行的目錄裡面 按照上面的步驟配置完環境後,接下來進行測試 的讀取要用到opencv,我就假設大家opencv配置均不存在問題 下面的 為我參考的官方給的一些資料,但是我用的opencv是3.4的,因此程式有些小小的改動,具體可參考如...
虹軟人臉識別Android Sample Code
afr fsdkinte ce engine new afr fsdkengine 用來存放提取到的人臉資訊,face 1 是註冊的人臉,face 2 是要識別的人臉 afr fsdkface face1 new afr fsdkface afr fsdkface face2 new afr fsd...