如何解决是否可以直接访问变量而不是使用指针和解引用器给出不同的值?
| 我知道这是一个奇怪的问题,我冒着露出绿色的危险,但是我在这里扯头发。 我有一个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
}
注意,“ 1”是一个指针,并被分配了“ 2”的地址。我的应用程序是用C#编写的,因此没有任何此类指针malarkey。相应的位如下所示:
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 ++应用程序中,底线的行为类似,但此处始终保持相同。
这与缺少指向和取消引用有关吗?还是我完全把树弄错了?我是否做了其他明显愚蠢的事情?最重要的是:我如何使其工作?
更新:结构和外部
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.nZ.ToString()));
}
}
}
}
在这两种情况下(在C#中读取初始化为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位上执行。
我将在VS2010的两个项目中附加ZIP。
链接在这里:
http://hotfile.com/dl/115296617/9644496/testCS.zip.html
似乎您在该位置struct中设置了错误的值:/
,似乎sysconf.byNumDevices == 1
因此i <= sysconf.byNumDevices
仅循环一次,您正在读取未初始化的内存段。
尝试打印出sysconf.byNumDevices
,如果为1,则尝试跟踪该问题。
,.NET中的数组从零开始,而不是从一开始。可以吗?当然,.NET还具有严格的边界检查功能,因此我希望您对数组的“最后”访问也会由于异常而失败。
无法访问ѭ19消息源,我不确定还有什么要告诉您的。
,只是想一想:传递给您的方法时,实际上需要引用吗?
FlockOfBirds.BIRDFRAME frame = new FlockOfBirds.BIRDFRAME();
FlockOfBirds.birdGetMostRecentFrame(1,ref frame);
如果我没记错的话,那么在c#中,所有类都会通过引用传递。我可能会生气,但是您不是将裁判传递给裁判吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。