直接访问变量(而不是使用指针和解引用)会得到不同的值吗?
Could accessing a variable directly (rather than with a pointer and dereferecer) give different values?
我知道这是一个奇怪的问题,我冒着暴露我的新手的风险,但是我真的很紧张。
我有一个c++的例子,工作如预期。下面是这段麻烦的代码:
BIRDFRAME frame;
birdGetMostRecentFrame(GROUP_ID,&frame);
BIRDREADING *bird_data;
bird_time=frame.dwTime;
for(FBBloop=FBBstart; FBBloop<FBBend; FBBloop++ )
{
bird_data = &frame.reading[FBBloop];
// Do stuff
}
注意bird_data
是一个指针,并且被分配了frame.reading[FBBloop]
的地址。我的应用程序是用c#编写的,所以没有任何指针的废话。对应的位看起来像这样:
FlockOfBirds.BIRDFRAME frame = new FlockOfBirds.BIRDFRAME();
FlockOfBirds.birdGetMostRecentFrame(1, ref frame);
Console.WriteLine("T:{0}",frame.dwTime.ToString());
FlockOfBirds.BIRDREADING reading;
for (int k = 1; k <= sysconf.byNumDevices; k++)
{
reading = frame.readings[k];
Console.WriteLine(" [{0}][{1}][{2}]", reading.position.nX.ToString(), reading.position.nY.ToString(), reading.position.nZ.ToString());
}
问题在于,在c#示例中,只有reading[1]
具有有意义的数据。在c++示例中,bird_data[1]
和bird_data[2]
都有良好的数据。奇怪的是,reading[2-n]
并不都有零值,但似乎是随机和恒定的。下面是c#应用程序的输出:
T:17291325
[30708][-2584][-5220]
[-19660][1048][-31310]
T:17291334
[30464][-2588][-5600]
[-19660][1048][-31310]
T:17291346
[30228][-2600][-5952]
[-19660][1048][-31310]
T:17291354
[30120][-2520][-6264]
[-19660][1048][-31310]
T:17291363
[30072][-2388][-6600]
[-19660][1048][-31310]
请注意,每个条目的顶部三元组与它之前和之后的条目略有不同。在c++应用程序中,底线的行为类似,但在这里它始终保持不变。
这是否与缺少指向和解引用有关?还是我完全搞错了方向?我还做了什么蠢事吗?最重要的是:我如何让它工作?
Update: Structs &外面的
c++// Bird reading structure
typedef struct tagBIRDREADING
{
BIRDPOSITION position; // position of receiver
BIRDANGLES angles; // orientation of receiver, as angles
BIRDMATRIX matrix; // orientation of receiver, as matrix
BIRDQUATERNION quaternion; // orientation of receiver, as quaternion
WORD wButtons; // button states
}
BIRDREADING;
// Bird frame structure
//
// NOTE: In stand-alone mode, the bird reading is stored in reading[0], and
// all other array elements are unused. In master/slave mode, the "reading"
// array is indexed by bird number - for example, bird #1 is at reading[1],
// bird #2 is at reading[2], etc., and reading[0] is unused.
typedef struct tagBIRDFRAME
{
DWORD dwTime; // time at which readings were taken, in msecs
BIRDREADING reading[BIRD_MAX_DEVICE_NUM + 1]; // reading from each bird
}
BIRDFRAME;
BOOL DLLEXPORT birdGetMostRecentFrame(int nGroupID, BIRDFRAME *pframe);
c#: [StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct BIRDREADING
{
public BIRDPOSITION position;
public BIRDANGLES angles;
public BIRDMATRIX matrix;
public BIRDQUATERNION quaternion;
public ushort wButtons;
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct BIRDFRAME
{
public uint dwTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 127)]
public BIRDREADING[] readings;
}
[DllImport(@"Bird.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool birdGetMostRecentFrame(int nGroupID, ref BIRDFRAME frame);
**更新2:更多的结构:**
c++#pragma pack(1) // pack the following structures on one-byte boundaries
// Bird position structure
typedef struct tagBIRDPOSITION
{
short nX; // x-coordinate
short nY; // y-coordinate
short nZ; // z-coordinate
}
BIRDPOSITION;
// Bird angles structure
typedef struct tagBIRDANGLES
{
short nAzimuth; // azimuth angle
short nElevation; // elevation angle
short nRoll; // roll angle
}
BIRDANGLES;
// Bird matrix structure
typedef struct tagBIRDMATRIX
{
short n[3][3]; // array of matrix elements
}
BIRDMATRIX;
// Bird quaternion structure
typedef struct tagBIRDQUATERNION
{
short nQ0; // q0
short nQ1; // q1
short nQ2; // q2
short nQ3; // q3
}
BIRDQUATERNION;
#pragma pack() // resume normal packing of structures
c# [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BIRDPOSITION
{
public short nX;
public short nY;
public short nZ;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BIRDANGLES
{
public short nAzimuth; // azimuth angle
public short nElevation; // elevation angle
public short nRoll; // roll angle
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct BIRDMATRIX
{
public fixed short n[9];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BIRDQUATERNION
{
public short nQ0; // q0
public short nQ1; // q1
public short nQ2; // q2
public short nQ3; // q3
}
我试过你的结构在两个项目(c++/c#),它似乎工作正常。
我在c++中使用:
#include "stdafx.h"
#include "windows.h"
#pragma pack(1) // pack the following structures on one-byte boundaries
// Bird position structure
typedef struct tagBIRDPOSITION
{
short nX; // x-coordinate
short nY; // y-coordinate
short nZ; // z-coordinate
}
BIRDPOSITION;
// Bird angles structure
typedef struct tagBIRDANGLES
{
short nAzimuth; // azimuth angle
short nElevation; // elevation angle
short nRoll; // roll angle
}
BIRDANGLES;
// Bird matrix structure
typedef struct tagBIRDMATRIX
{
short n[3][3]; // array of matrix elements
}
BIRDMATRIX;
// Bird quaternion structure
typedef struct tagBIRDQUATERNION
{
short nQ0; // q0
short nQ1; // q1
short nQ2; // q2
short nQ3; // q3
}
BIRDQUATERNION;
#pragma pack() // resume normal packing of structures
typedef struct tagBIRDREADING
{
BIRDPOSITION position; // position of receiver
BIRDANGLES angles; // orientation of receiver, as angles
BIRDMATRIX matrix; // orientation of receiver, as matrix
BIRDQUATERNION quaternion; // orientation of receiver, as quaternion
WORD wButtons; // button states
}
BIRDREADING;
#define BIRD_MAX_DEVICE_NUM 126
// Bird frame structure
//
// NOTE: In stand-alone mode, the bird reading is stored in reading[0], and
// all other array elements are unused. In master/slave mode, the "reading"
// array is indexed by bird number - for example, bird #1 is at reading[1],
// bird #2 is at reading[2], etc., and reading[0] is unused.
typedef struct tagBIRDFRAME
{
DWORD dwTime; // time at which readings were taken, in msecs
BIRDREADING reading[BIRD_MAX_DEVICE_NUM + 1]; // reading from each bird
}
BIRDFRAME;
extern "C" __declspec( dllexport ) BOOL birdGetMostRecentFrame(int nGroupID, BIRDFRAME *pframe) {
pframe->dwTime = GetTickCount();
for (int i = 0; i < sizeof(pframe->reading)/sizeof(*pframe->reading); i++) {
pframe->reading[i] = BIRDREADING();
pframe->reading[i].position.nX = (short)i;
pframe->reading[i].position.nY = (short)i + 1;
pframe->reading[i].position.nZ = (short)i + 2;
}
return TRUE;
}
在c#中:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BIRDPOSITION
{
public short nX;
public short nY;
public short nZ;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BIRDANGLES
{
public short nAzimuth; // azimuth angle
public short nElevation; // elevation angle
public short nRoll; // roll angle
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct BIRDMATRIX
{
public fixed short n[9];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BIRDQUATERNION
{
public short nQ0; // q0
public short nQ1; // q1
public short nQ2; // q2
public short nQ3; // q3
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct BIRDREADING
{
public BIRDPOSITION position;
public BIRDANGLES angles;
public BIRDMATRIX matrix;
public BIRDQUATERNION quaternion;
public ushort wButtons;
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct BIRDFRAME
{
public uint dwTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 127)]
public BIRDREADING[] readings;
}
public partial class Form1 : Form
{
[DllImport(@"Bird.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool birdGetMostRecentFrame(int nGroupID, ref BIRDFRAME frame);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
BIRDFRAME bf = new BIRDFRAME();
if (checkBox1.Checked)
{
bf.readings = new BIRDREADING[127];
}
if (birdGetMostRecentFrame(0, ref bf)) {
listBox1.Items.Add(bf.dwTime.ToString());
Console.WriteLine(bf.dwTime.ToString());
for (int k = 1; k <= 3; k++)
{
var reading = bf.readings[k];
Console.WriteLine(String.Format(" [{0}][{1}][{2}]", reading.position.nX.ToString(), reading.position.nY.ToString(), reading.position.nZ.ToString()));
listBox1.Items.Add(String.Format(" [{0}][{1}][{2}]", reading.position.nX.ToString(), reading.position.nY.ToString(), reading.position.nZ.ToString()));
}
}
}
}
在这两种情况下(在c#中读取初始化为new或不初始化为new),都会返回有意义的数据:
40067905
[1][2][3]
[2][3][4]
[3][4][5]
40068653
[1][2][3]
[2][3][4]
[3][4][5]
40069418
[1][2][3]
[2][3][4]
[3][4][5]
40072585
[1][2][3]
[2][3][4]
[3][4][5]
在Windows7 64位上做的。我附加了一个ZIP与VS2010的两个项目。
链接:
http://hotfile.com/dl/115296617/9644496/testCS.zip.html似乎你在那个位置结构中设置了错误的值:/
似乎sysconf.byNumDevices == 1
和i <= sysconf.byNumDevices
只循环一次,你正在读取未初始化的内存段。
试着打印出sysconf.byNumDevices
,如果是1,试着跟踪这个问题
. net中的数组是基于零的,而不是基于一的。会是这样吗?当然,. net也有严格的边界检查,所以我希望你对数组的"最后"访问也会因异常而失败。
没有访问FlockOfBirds
源,我不确定还有什么要告诉你的
只是一个想法:当传递给你的方法时,你真的需要ref吗?
FlockOfBirds.BIRDFRAME frame = new FlockOfBirds.BIRDFRAME();
FlockOfBirds.birdGetMostRecentFrame(1, ref frame);
如果我没弄错的话,那么c#中所有的类都是通过引用传递的。我可能很生气,但你不是在把裁判传给裁判吗?
- C++取消引用指针.为什么会发生变化
- 深层复制具有自引用指针的类
- Visual c ++,使用字符串引用/指针调用 dll 函数
- std::unordered_map::提取引用/指针失效
- 为什么在引用指针时将 const 放在 & 符号的左侧有效,而在右侧则无效?
- 区分接受常量参数的函数引用/指针和与函数参数同名的非常量参数
- 如何在 c++ 中使用带有数学运算的引用/指针?
- 了解通过引用传递取消引用指针时C++堆/堆栈分配
- 取消引用指针并立即为其分配变量,导致分段错误
- 如何获取指向类(而不是对象)的引用/指针
- 将类型参数传递给自引用指针
- 我应该如何定义返回指针的函数?(引用指针与指针指针)
- 在析构函数内取消引用指针时出现分段错误
- 来自引用指针的内存泄漏
- 引用指针后面的值
- 无法取消引用指针
- 引用指针调用成员函数
- 未定义的引用指针的变量模板在clang中功能,而不是GCC
- 取消引用指针以创建数组的副本
- 有关启动引用指针的引用的问题