从托管 (C#) 调用不安全代码。读取字节数组

发布于 2024-09-27 23:34:48 字数 930 浏览 10 评论 0原文

我有这个方法,我需要在我的应用程序中调用和使用,但我不知道如何准确地做到这一点。

这是我需要调用的函数。

[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 - 读取的实际数据大小。

I have this method that I need to call and use in my application, but I don't know really know how to do it exactly.

This is the function that I need to call.

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

In my code, I have this function and I'm missing its implementation.

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

I think most of this is very selfexplanatory. I need to implement the latter function so I can be able to read the data into the buffer and the amount of data read (which should actually be the same as data.Length, but the manufacturer has this as separate option, so I need it).
Can anyone help? Is this clear enough?

Thank you

Edit: Here is the unmanaged declaration from the .h file. Hope it helps.

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

Edit #2:
Positon - the position from which to star reading the data.
Length - The amount of data to read (this would be the buffer size).
DataRead - the actual data size that was read.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吻风 2024-10-04 23:34:48

我认为你真的不需要在这里使用不安全指针。
将函数声明

[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;
            }
    }
}

I don't think you really need to use unsafe pointers here.
Declare function as

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

Reasonable C# wrapper for this function:

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;
            }
    }
}
前事休说 2024-10-04 23:34:48

我无法对此进行测试,但我认为您应该让封送拆收器进行转换:

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

I can't test this but I think you should let the Marshaler do you conversion(s):

[DllImport(dll_Path)]
public static extern int DTS_GetDataToBuffer(out byte[] data, out int dataRead);
请恋爱 2024-10-04 23:34:48

我同意你不需要使用不安全块。您正在使用 pinvoke,我希望以下链接可能有用:
http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
http://www.pinvoke.net/

并且 stackoverflow 上也有帖子

i agree you don't need to use unsafe block. you are using pinvoke, i hope below links might be useful :
http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
http://www.pinvoke.net/

and there are post on stackoverflow too

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文