簡體   English   中英

從托管(C#)調用不安全的代碼。 讀取字節數組

[英]Calling unsafe code from managed (C#). Reading byte array

我有需要在我的應用程序中調用和使用的這種方法,但是我不知道如何確切地做到這一點。

這是我需要調用的函數。

[DllImport(dll_Path)]
public static extern int DTS_GetDataToBuffer(int Position, int Length, char* Buffer, int* DataRead);

在我的代碼中,我有此功能,但我沒有實現它。

internal static void GetDataToBuffer(int position, int length, out byte[] data, out int dataRead)
    {
        unsafe
        {
             // the code I need
        }
    }

我認為大部分內容都是不言而喻的。 我需要實現后一個功能,以便能夠將數據讀入緩沖區和讀取的數據量(實際上應該與data.Length相同,但是制造商將其作為單獨的選項,因此我需要它)。 有人可以幫忙嗎? 這足夠清楚嗎?

謝謝

編輯:這是.h文件中的非托管聲明。 希望能幫助到你。

 extern NAG_DLL_EXPIMP int DTS_GetDataToBuffer(int Position, 
                               int Length, 
                               unsigned char  *Buffer, 
                               int *DataRead );

編輯#2:位置-從星號讀取數據的位置。 長度-要讀取的數據量(這是緩沖區大小)。 DataRead-讀取的實際數據大小。

我認為您真的不需要在這里使用不安全的指針。 聲明為

[DllImport(dll_Path)]
public static extern int DTS_GetDataToBuffer(
    int     position,
    int     length,
    byte[]  buffer,
    ref int dataRead);

此功能的合理C#包裝器:

internal static byte[] GetDataToBuffer()
{
    // set BufferSize to your most common data length
    const int BufferSize = 1024 * 8;
    // list of data blocks
    var chunks = new List<byte[]>();
    int dataRead = 1;
    int position = 0;
    int totalBytes = 0;
    while(true)
    {
        var chunk = new byte[BufferSize];
        // get new block of data
        DTS_GetDataToBuffer(position, BufferSize, chunk, ref dataRead);
        position += BufferSize;
        if(dataRead != 0)
        {
            totalBytes += dataRead;
            // append data block
            chunks.Add(chunk);
            if(dataRead < BufferSize)
            {
                break;
            }
        }
        else
        {
            break;
        }
    }
    switch(chunks.Count)
    {
        case 0: // no data blocks read - return empty array
            return new byte[0];
        case 1: // single data block
            if(totalBytes < BufferSize)
            {
                // truncate data block to actual data size
                var data = new byte[totalBytes];
                Array.Copy(chunks[0], data, totalBytes);
                return data;
            }
            else // single data block with size of Exactly BufferSize
            {
                return chunks[0];
            }
        default: // multiple data blocks
            {
                // construct new array and copy all data blocks to it
                var data = new byte[totalBytes];
                position = 0;
                for(int i = 0; i < chunks.Count; ++i)
                {
                    // copy data block
                    Array.Copy(chunks[i], 0, data, position, Math.Min(totalBytes, BufferSize));
                    position += BufferSize;
                    // we need to handle last data block correctly,
                    // it might be shorted than BufferSize
                    totalBytes -= BufferSize;
                }
                return data;
            }
    }
}

我無法對此進行測試,但我認為您應該讓Marshaler進行轉換:

[DllImport(dll_Path)]
public static extern int DTS_GetDataToBuffer(out byte[] data, out int dataRead);

我同意您不需要使用不安全的阻止。 您正在使用pinvoke,希望以下鏈接可能有用: http : //msdn.microsoft.com/zh-cn/magazine/cc164123.aspx http://www.pinvoke.net/

而且也有關於stackoverflow的帖子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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