仅从第一个元素访问 C# 数组
C# array access from first element only
很抱歉,如果之前有人问过这个问题,但我什至不知道要搜索什么才能找到答案。
我在 .net/c# 等方面相当有经验,但是,我遇到了一些我不明白它是如何工作的东西。
我在第三方库上工作,我无法访问源代码。
我的问题是:
当仅传递第一个值时,此函数如何能够获取数组中的全部数据?
原型:
SomeClass(ref byte pByte, int length);
代码示例:
...
byte[] bArr = new byte[100];
// fill array with some data
SomeClass(ref bArr[0], bArr.Length);
...
更新:
抱歉,我一开始就没有将其包含在 post 中。
我是一名经验丰富的嵌入式固件工程师,但我也使用 c#/.net/wpf/wcf 等多年。所以我很清楚 pass-by-value/reference 和 ref 修饰符的区别。
我最初的困惑是,我从未见过任何 c# 函数调用只传递数组中的第一个元素(如 c/c++ 中的指针)并且该函数可以访问整个数组。因此,吸引我的更多是语法。 :)
感谢@jdweng 的评论,我使用 iLSpy 确认了 Nicholas Carey 的回答。该库只是一个 CLR 包装的 c++ 库,其中完成了 dll 导入和封送处理。
谢谢大家的回答。 :)
数组是一块连续的内存,调用这样的函数:
foo( ref bAarr[0], bArr.Length );
它传递了两件事:
- 数组第一个元素的地址,
- 数组中的元素个数
您的第 3 方库几乎可以肯定是一个 C/C++ DLL,按照
的方式公开函数签名
int foo( unsigned char *p, int len );
像arr[n]
这样的数组引用[大致]等同于以下伪代码:
- 设
p
为arr
的地址
- 让
offset
n
乘以数组基础类型的八位字节大小
- 令
pElement
为p
+ offset
,数组arr
. 的元素n
的地址
pElement
,取消引用时,为您提供 arr[n]
.
的值
@Nicholas 解释了它是如何发生的,但是如果你想在 C# 中做同样的事情,请检查下面的代码:
不推荐使用,满足好奇心:
void Main()
{
byte[] bArr = new byte[100];
// fill the entire array without passing it to method
FillEntireArray(ref bArr[0], bArr.Length);
// read the entire array without passing it to method
ReadEntireArray(ref bArr[0], bArr.Length);
}
public unsafe void FillEntireArray(ref byte pByte, int length)
{
fixed (byte* ptr = &pByte)
{
byte* p = ptr;
for (int i = 0; i < length; i++)
{
// set a new value to pointer
*p = ((byte)(i));
// move pointer to next item
p++;
}
}
}
public unsafe void ReadEntireArray(ref byte pByte, int length)
{
fixed (byte* ptr = &pByte)
{
byte* p = ptr;
for (int i = 0; i < length; i++)
{
// Print the value of *p:
Console.WriteLine($"Value at address 0x{(int)p:X} is {p->ToString()}");
// move pointer to next item
p++;
}
}
}
缩写形式:
public unsafe void FillArray(ref byte arr, int length)
{
fixed (byte* ptr = &arr)
{
for (byte i = 0; i<length; i++)
{
*(ptr + i) = i;
}
}
}
很抱歉,如果之前有人问过这个问题,但我什至不知道要搜索什么才能找到答案。
我在 .net/c# 等方面相当有经验,但是,我遇到了一些我不明白它是如何工作的东西。
我在第三方库上工作,我无法访问源代码。
我的问题是: 当仅传递第一个值时,此函数如何能够获取数组中的全部数据?
原型:
SomeClass(ref byte pByte, int length);
代码示例:
...
byte[] bArr = new byte[100];
// fill array with some data
SomeClass(ref bArr[0], bArr.Length);
...
更新: 抱歉,我一开始就没有将其包含在 post 中。 我是一名经验丰富的嵌入式固件工程师,但我也使用 c#/.net/wpf/wcf 等多年。所以我很清楚 pass-by-value/reference 和 ref 修饰符的区别。 我最初的困惑是,我从未见过任何 c# 函数调用只传递数组中的第一个元素(如 c/c++ 中的指针)并且该函数可以访问整个数组。因此,吸引我的更多是语法。 :)
感谢@jdweng 的评论,我使用 iLSpy 确认了 Nicholas Carey 的回答。该库只是一个 CLR 包装的 c++ 库,其中完成了 dll 导入和封送处理。
谢谢大家的回答。 :)
数组是一块连续的内存,调用这样的函数:
foo( ref bAarr[0], bArr.Length );
它传递了两件事:
- 数组第一个元素的地址,
- 数组中的元素个数
您的第 3 方库几乎可以肯定是一个 C/C++ DLL,按照
的方式公开函数签名int foo( unsigned char *p, int len );
像arr[n]
这样的数组引用[大致]等同于以下伪代码:
- 设
p
为arr
的地址
- 让
offset
n
乘以数组基础类型的八位字节大小 - 令
pElement
为p
+offset
,数组arr
. 的元素
n
的地址
pElement
,取消引用时,为您提供 arr[n]
.
@Nicholas 解释了它是如何发生的,但是如果你想在 C# 中做同样的事情,请检查下面的代码:
不推荐使用,满足好奇心:
void Main()
{
byte[] bArr = new byte[100];
// fill the entire array without passing it to method
FillEntireArray(ref bArr[0], bArr.Length);
// read the entire array without passing it to method
ReadEntireArray(ref bArr[0], bArr.Length);
}
public unsafe void FillEntireArray(ref byte pByte, int length)
{
fixed (byte* ptr = &pByte)
{
byte* p = ptr;
for (int i = 0; i < length; i++)
{
// set a new value to pointer
*p = ((byte)(i));
// move pointer to next item
p++;
}
}
}
public unsafe void ReadEntireArray(ref byte pByte, int length)
{
fixed (byte* ptr = &pByte)
{
byte* p = ptr;
for (int i = 0; i < length; i++)
{
// Print the value of *p:
Console.WriteLine($"Value at address 0x{(int)p:X} is {p->ToString()}");
// move pointer to next item
p++;
}
}
}
缩写形式:
public unsafe void FillArray(ref byte arr, int length)
{
fixed (byte* ptr = &arr)
{
for (byte i = 0; i<length; i++)
{
*(ptr + i) = i;
}
}
}