【发布时间】:2011-08-06 14:26:48
【问题描述】:
我知道这是一个奇怪的问题,我冒着表现出我的绿色的风险,但我在这里扯掉了我的头发。
我有一个按预期工作的 C++ 示例。这是一个麻烦的部分的sn-p:
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++ 应用程序中,底线的行为类似,但在这里始终保持不变。
这可能与缺乏指向和取消引用有关吗?还是我在吠叫完全错误的树?我做了其他明显愚蠢的事情吗?最重要的是:如何让它发挥作用?
更新:结构和外部
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
}
【问题讨论】:
-
我不能说我理解你所有的对象可能在做什么,或者为什么这不会导致失败但大多数数组都是从零开始的,这肯定应该以
int k = 1;开头? -
是的,这很奇怪,但绝对是从 1 开始。0 保留用于只有一个值要查询的特殊情况。
-
"0 是为只有一个值的特殊情况保留的" - 因此,如果您有 2 个项目,则数组中将包含 3 个元素,而索引 0 处的第一个元素未被使用?如果是这样,似乎应该对此进行一些思考。特别是因为索引 0 已经很好地处理了一项数组的“特殊情况”。
-
嘿,库不是我写的! ;) 如果你想要胆量,数组总是固定在 127。如果只连接一台仪器并且处于“独立”模式,则索引 1-126 将被忽略。如果像我的情况一样,连接了 2,则忽略 0 和 3-126。
-
如果没有结构的定义和
birdGetMostRecentFrame背后的一些知识,我们只能猜测。是否也有一些 P/Invoke 混合在某个地方?