[英]How can I get IntPtr pointer from object
我正在開發指紋設備,制造商(Upek)給了我一個 c++ BSAPI.dll 所以我需要使用包裝器才能讓它在 Z2D50972FCECD376129545507F106208 中工作
我可以在內存中處理這一切,我可以抓取並匹配指紋。
現在我一直試圖將數據導出到文件中,然后將其加載回 memory 並獲取 IntPtr。
這里有一個關於如何從文件導出和導入的 c++ 示例。 但我不知道怎么讀。
感謝任何幫助謝謝大家
這就是我所擁有的並且效果很好:
現在我需要兩件事 1. 將那個 bufBIR 保存到數據庫中。 2. 把我保存的數據傳給abs_verify。
如何才能做到這一點?
我不知道問題的主體是什么意思,但要回答標題:
如何從 object 獲得 IntPtr?
這是故意要求做一些工作的,這是有充分理由的。 垃圾收集器通常可以重新定位 memory 中的對象,因此只能通過“固定”它來完成。 為此,您必須使用GCHandleType 'Pinned' 創建一個GCHandle ,然后您可以調用GCHandle.AddrOfPinnedObject 。 如果未固定,這將引發異常。
您還應該注意GCHandle.ToIntPtr返回句柄的值而不是 object 的地址。 這基本上用於有一個可以在重構 GCHandle 之前輕松傳遞的整數值。
這是很久以前我得到的 C# 代碼(我認為來自 BIOAPI 示例代碼),用於與BioAPI接口。 DoMarshall 方法返回一個 IntPtr 指向分配的 memory 足夠大以容納數組。
我沒有使用托管 C++,所以我不確定需要進行哪些更改,但也許它會為您指明正確的方向。 當時我正在與 UPEK 合作。 我希望這有幫助...
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public class BioAPI_DATA
{
public uint Length = 0;
public byte[] Data = null;
public BioAPI_DATA() {}
public BioAPI_DATA(uint length, byte[] data) { Length = length; Data = data; }
public IntPtr DoMarshal(ref int size)
{
IntPtr ptr;
IntPtr ptrData = IntPtr.Zero;
int ofs = 0;
size = Marshal.SizeOf(Type.GetType("System.Int32")) +
Marshal.SizeOf(Type.GetType("System.IntPtr"));
ptr = Marshal.AllocCoTaskMem( size );
Marshal.WriteInt32(ptr, ofs, (int) Length);
ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
if (Data != null)
{
ptrData = Marshal.AllocCoTaskMem( Data.Length );
Marshal.Copy(Data, 0, ptrData, Data.Length);
}
Marshal.WriteIntPtr(ptr, ofs, ptrData);
return ptr;
}
public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
{
int ofs = 0;
size = Marshal.SizeOf(Type.GetType("System.Int32")) +
Marshal.SizeOf(Type.GetType("System.IntPtr"));
Length = (uint) Marshal.ReadInt32( ptr, ofs );
ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
if (Length == 0)
{
if (Data != null) Data = null;
return;
}
IntPtr ptr2 = Marshal.ReadIntPtr(ptr, ofs);
if (Data == null || Data.Length != Length) Data = new byte[Length];
Marshal.Copy(ptr2, Data, 0, (int) Length);
if (fDeleteOld) { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
}
}
IntPtr
只是void*
的 .NET 類型。 它本身並不意味着任何意義。 您需要知道 memory 包含什么,並確保 .NET 和 C 側使用相同的 ZCD69B7BF357F06CD8D9D161 布局。
您可以通過兩種主要方式在托管代碼和非托管代碼之間進行交互。
一種是 C++/CLI (IJW)。 如果您固定托管 object 或陣列,則可以將其傳遞到非托管 function。 但是,對於復雜類型,您可能會遇到麻煩,因為 .NET 的 memory 布局不一定與您的 C 庫所期望的相同。 檢查pin_ptr以獲取更多信息。
第二種流行的方法是使用p/invoke ,您可以將 C# struct
(C++/CLI value struct
)編組為 C struct
,甚至是這些結構的數組。 您可以指定 memory 布局、 string
是否應編組為 MBCS 或 UTF-16、結構應如何對齊等。 以這種方式直接從 C# 調用 C 函數很容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.