从非托管代码传递指针 [英] Passing pointers from unmanaged code

查看:82
本文介绍了从非托管代码传递指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个导入C dll的C#项目,该dll具有以下功能:

I have a C# project that imports a C dll, the dll has this function:

int primary_read_serial(int handle, int *return_code, int *serial, int length);

我想访问串行参数。实际上,我已经得到它返回串行参数的一个字符,但是我不确定自己在做什么,是否想了解正在发生什么,当然可以使其正常工作。

I want to get access to the serial parameter. I've actually got it to return one character of the serial parameter, but I'm not really sure what I'm doing and would like to understand what is going, and of course get it working.

因此,我非常确定正在访问该dll,其他没有指针的功能也可以正常工作。我该如何处理指针?我需要封送吗?

So, I'm very sure that the dll is being accessed, other functions without pointers work fine. How do I handle pointers? Do I have to marshal it? Maybe I have to have a fixed place to put the data it?

也许会需要一个固定的位置来存放数据?

An explanation would be great.

谢谢!
理查德

Thanks! Richard

推荐答案

您将必须使用IntPtr并将该IntPtr编组到要放置的任何C#结构中

You will have to use an IntPtr and Marshal that IntPtr into whatever C# structure you want to put it in. In your case you will have to marshal it to an int[].

这是分几个步骤完成的:

This is done in several steps:


  • 分配一个非托管句柄

  • 使用未管理的数组调用该函数

  • 将数组转换为托管字节数组

  • 将字节数组转换为整数数组

  • 释放非托管句柄

  • Allocate an unmanaged handle
  • Call the function with the unamanged array
  • Convert the array to managed byte array
  • Convert byte array to int array
  • Release unmanaged handle

该代码应该给您一个想法:

That code should give you an idea:

// The import declaration
[DllImport("Library.dll")]
public static extern int primary_read_serial(int, ref int, IntPtr, int) ;


// Allocate unmanaged buffer
IntPtr serial_ptr = Marshal.AllocHGlobal(length * sizeof(int));

try
{
    // Call unmanaged function
    int return_code;
    int result = primary_read_serial(handle, ref return_code, serial_ptr, length);

    // Safely marshal unmanaged buffer to byte[]
    byte[] bytes = new byte[length * sizeof(int)];
    Marshal.Copy(serial_ptr, bytes, 0, length);

    // Converter to int[]
    int[] ints = new int[length];
    for (int i = 0; i < length; i++)
    {
        ints[i] = BitConverter.ToInt32(bytes, i * sizeof(int));
    }

}
finally
{
    Marshal.FreeHGlobal(serial_ptr);
}

别忘了最后尝试,否则您可能会泄漏不受管理的内容

Don't forget the try-finally, or you will risk leaking the unmanaged handle.

这篇关于从非托管代码传递指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆