Неожиданные результаты при сортировке списка структур - PullRequest
0 голосов
/ 12 января 2019

Я не мог понять, что я делаю не так. Я думаю, что я делаю все по номерам, но похоже, что я что-то упустил.

На управляемой стороне:

public override List<TimerPair> GetNativeTimers()
{
    var listPtr = HgrDll.GetNativeTimers(out var size, out var ptrShift);

    if (listPtr == IntPtr.Zero)
        throw new NullReferenceException("sounds like the list"
             + " pointer was not given");

    var timerPairList = new List<TimerPair>(size);
    var structSize = Marshal.SizeOf(typeof(TimerPairStruct2));

    for (var i = 0; i < size; i++)
    {
        var o = Marshal.PtrToStructure<TimerPairStruct2>(listPtr).ToTimerPair();
        timerPairList.Add(o);
        listPtr += structSize;
    }
    return timerPairList;
}

Целевая структура (используется для промежуточных вычислений) и класс:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal struct TimerPairStruct2 : ITimerPairStruct
{
    public long Time;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]
    public string Descr;

    public TimerPair ToTimerPair() => new TimerPair(Descr, Time);
}

public class TimerPair
{
    public string Descr { get; set; }
    public TimeSpan Time { get; set; }
    public TimerPair(string descr, long time)
    {
        Descr = descr;
        Time = new TimeSpan(0,0,0,0, (int)((double)time/1000000));
    }
}

Для части Pinvoke:

[DllImport("DwarfHomograph.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr GetNativeTimers(out int size, out int ptrShift);

и теперь на родной стороне:

DwarfHgr* DwarfAsset = nullptr;

extern "C" __declspec(dllexport) list<TimerPair>* GetNativeTimers(
    int* size,
    int* ptrShift)
{
    return DwarfAsset->GetNativeTimers(size, ptrShift);
}

используемый метод из класса DwarfHgr:

list<TimerPair>* DwarfHgr::GetNativeTimers(int* size, int* ptrShift)
{
    TimerPairsList = Sw.AsTimerPairs();
    *size = static_cast<int>(TimerPairsList.size());
    *ptrShift = sizeof(TimerPair);
    return &TimerPairsList;
}

и член list<TimerPair> TimerPairsList;

Структура, которой я занимаюсь:

//#pragma pack(push,8)
struct __declspec(dllexport) TimerPair final
{
    long long Time{}; // ns
    char Descr[64]{};
};
//#pragma pack(pop)

У меня модульные тесты как на нативной, так и на управляемой сторонах; ожидаемый результат выглядит (нативно):

ImageA processing: 22.0704ms
ImageB processing: 22.0448ms
MatFullA.copyTo: 1.87452ms
MatToSparse: 1.93482ms
calcOpticalFlowFarneback: 1115.48ms
create flowSparse image: 10.1416ms

Но у меня есть это (удалось):

°óŠqÉ: 1,964,675.000000ms
q$Fý: 140,725,780.000000ms
xr$Fý: 140,725,780.000000ms
: 549,755.000000ms
à¡CUÉ: 1,964,675.000000ms
: 0.000000ms
...