2016-11-23 3 views
0

Я работаю над проектом, который должен связываться с DLL. Предоставляемый SDK имеет демонстрационный проект на C++, и он возвращает данные из DLL, используя указанную выше структуру typedef, и он работает хорошо, но я должен сделать то же самое, но в C#, и я попытался создать подобную структуру, но когда я вызываю DLL моя структура заполнена в другом порядке.Эквивалент C++ typedef struct to C#

typedef struct tagTrackIRData 
{ 
    unsigned short wNPStatus; 
    unsigned short wPFrameSignature; 
    unsigned long dwNPIOData; 

    float fNPRoll; 
    float fNPPitch; 
    float fNPYaw; 
    float fNPX; 
    float fNPY; 
    float fNPZ; 
    float fNPRawX; 
    float fNPRawY; 
    float fNPRawZ; 
    float fNPDeltaX; 
    float fNPDeltaY; 
    float fNPDeltaZ; 
    float fNPSmoothX; 
    float fNPSmoothY; 
    float fNPSmoothZ; 
} TRACKIRDATA, *LPTRACKIRDATA; 

Проблема заключается в том, что я получил в C# Если структура выше, но я не могу назначить его в том же формате структуры в C# (The структура является из библиотеки DLL C++ и моя программа, назвав его в C#). Я попытался использовать этот тип преобразованной структуры в C#, но данные не попадают в правильное имя переменной, вероятно, из-за отсутствия * LPTRACKIRDATA.

struct TRACKIRDATA 
{ 
    public ushort wNPStatus; 
    public ushort wPFrameSignature; 
    public ulong dwNPIOData; 

    public float fNPRoll; 
    public float fNPPitch; 
    public float fNPYaw; 
    public float fNPX; 
    public float fNPY; 
    public float fNPZ; 
    public float fNPRawX; 
    public float fNPRawY; 
    public float fNPRawZ; 
    public float fNPDeltaX; 
    public float fNPDeltaY; 
    public float fNPDeltaZ; 
    public float fNPSmoothX; 
    public float fNPSmoothY; 
    public float fNPSmoothZ; 
} 

Я звоню DLL в C# с помощью этого кода:

TRACKIRDATA tid; 
NPRESULT gdRes = getData(&tid); 

Где GetData() является

private delegate NPRESULT NP_GetData(TRACKIRDATA* data); 
getData = (NP_GetData)Marshal.GetDelegateForFunctionPointer(procAddrNP_GetData, typeof(NP_GetData)); 

Благодаря @Asik вы были правы! Проблема была вызвана неправильным эквивалентом типа dwNPIOData, потому что именованный long на C++ - 32Bits, а в C# - размер 64 бит. Решение заключается в использовании типа UInt32 в C# public uint dwNPIOData;

+3

Вам не нужны структуры typedef в C++. Это откат от C. – juanchopanza

+0

В чем проблема? – SLaks

+0

@juanchopanza Полезно знать, но dll C++ не принадлежит мне, и я просто вызываю метод из DLL в моем приложении C#, поэтому мне приходится обрабатывать ожидаемую структуру. – exomic

ответ

4

Имейте в виду целочисленных типов не означают одно и то же в C++ и C#. В частности, long означает at least 32 bits в C++, но это означает strictly 64 bits в C# *. Выравнивание также может отличаться, поскольку вы не укажете его явно на любом языке.

Вкратце, вам нужно будет использовать эквивалентные типы и обеспечить, чтобы выравнивание было точно таким же, как и для отображения. Это не имеет никакого отношения к «отсутствующей * LPTRACKIRDATA».

* Вопрос первоначально был C# ulong вместо uint.

+0

Спасибо за информацию, я изменил ulong на uint (uint32), и теперь тип будет соответствовать. Я думаю, что остальное - правильный эквивалент типа. – exomic

+0

После дальнейшего тестирования заказ теперь тот же, что и вы, проблема была улонг (размер 32 на C++ не совпадает с улугом на C#, который является 64 бит), изменив его на uint, исправил проблему. – exomic