簡體   English   中英

如何從 object 獲取 IntPtr 指針

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM