Обработка вложенных структур из неуправляемого cpp в управляемый c # с использованием IntPtr - PullRequest
0 голосов
/ 19 сентября 2018

Я пытаюсь присвоить значения массиву структур в управляемом c # и обращаюсь к нему в cpp.

Рассмотрим следующие структуры в cpp:

struct NSCASR_RCG_ITEM_ST
{
    char* pstrSlotName;
    char* pstrReportedText;
    short usConfidence;
    unsigned long ulLocation;
    unsigned long ulDuration;
};

struct NSCASR_RCG_PHRASE_ST
{
    unsigned short usConfidence;
    unsigned short usNumItems;
    short sGrammarIndex;
    short sGrammarType;
    NSCASR_RCG_ITEM_ST Item[1];
};     

struct NSCASR_RCG_RES_ST
{
    unsigned long ulSizeBytes;
    unsigned long ulWarnings;
    unsigned short usNumPhrases;
    char*  pstrWaveformURI;
    unsigned long ulWaveformSizeBytes;
    unsigned long ulWaveformDuration;
    NSCASR_RCG_PHRASE_ST * pPhrase[1];
};

Рассмотрим следующееструктуры в c #:

[StructLayout(LayoutKind.Explicit,CharSet = CharSet.Ansi)]
public struct NSCASR_RCG_ITEM_ST
{
    [FieldOffset(0)]
    public IntPtr pstrSlotName;
    [FieldOffset(4)]
    public IntPtr pstrReportedText;
    [FieldOffset(8)]
    public ushort usConfidence;
    [FieldOffset(10)]
    public uint ulLocation;
    [FieldOffset(14)]
    public uint ulDuration;
}

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct NSCASR_RCG_PHRASE_ST
{
    [FieldOffset(0)]
    public ushort usConfidence;
    [FieldOffset(2)]
    public ushort usNumItems;
    [FieldOffset(4)]
    public short sGrammarIndex;
    [FieldOffset(6)]
    public short sGrammarType;
    [FieldOffset(8)]
    public IntPtr Item;/*This holds pointer to NSCASR_RCG_ITEM_ST*/
}


[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public unsafe struct NSCASR_RCG_RES_ST
{

    [FieldOffset(0)]
    public uint ulSizeBytes;
    [FieldOffset(4)]
    public uint ulWarnings;
    [FieldOffset(8)]
    public ushort usNumPhrases;
    [FieldOffset(12)]
    public IntPtr pstrWaveformURI;
    [FieldOffset(16)]
    public uint ulWaveformSizeBytes;
    [FieldOffset(20)]
    public uint ulWaveformDuration;
    [FieldOffset(24)]
    public IntPtr pPhrase;/*This holds pointer to NSCASR_RCG_PHRASE_ST*/
}

Используя вышеупомянутые структуры, я присваиваю значения членам структуры NSCASR_RCG_ITEM_ST следующим образом:

public unsafe static int ASR_Recognize_ResultsGet(ref Constants.NSCASR_RCG_RES_ST pRecognitionResults)
{
    Constants.NSCASR_RCG_PHRASE_ST[] test = new Constants.NSCASR_RCG_PHRASE_ST[1];
    Constants.NSCASR_RCG_ITEM_ST[] itm = new Constants.NSCASR_RCG_ITEM_ST[1];
    itm[0].pstrSlotName = Marshal.StringToHGlobalAnsi("123");
    itm[0].pstrReportedText = Marshal.StringToHGlobalAnsi("456");
    itm[0].usConfidence = 789;
    itm[0].ulLocation = 888;
    itm[0].ulDuration = 999;

    GCHandle arrHandle = GCHandle.Alloc(test, GCHandleType.Pinned);
    GCHandle itmhandle = GCHandle.Alloc(itm, GCHandleType.Pinned);

    try
    {
        test[0].Item = itmhandle.AddrOfPinnedObject();
        pRecognitionResults.pPhrase = arrHandle.AddrOfPinnedObject();    
    }
    catch (Exception ex)
    {

    }
    finally
    {
        arrHandle.Free();
        itmhandle.Free();
    }
}

Но я не могу получить доступ к данным в cpp.Ниже приведен код cpp, к которому я обращаюсь к членам

NSCASR_RCG_RES_ST phrase[2] = { 0 };
int _tmain()
{
    int *result;

    NSCASR_RCG_PHRASE_ST * ptr1;
    NSCASR_RCG_RES_ST *rec = (NSCASR_RCG_RES_ST *)phrase;
    NSCASR_RCG_ITEM_ST item[1];

    ASR_Recognize_ResultsGet(rec);

    ptr1 = rec->pPhrase[0];
    for (int i = 0; i < 10; i++)
    {
        printf("\n%d--%s", i, ptr1[i].Item[i].pstrSlotName);
        printf("\n%d--%s", i, ptr1[i].Item[i].pstrReportedText);
        printf("\n%d--%d", i, ptr1[i].Item[i].usConfidence);
        printf("\n%d--%d", i, ptr1[i].Item[i].ulLocation);
        printf("\n%d--%d", i, ptr1[i].Item[i].ulDuration);
        printf("\n%d--%d", i, ptr1[i].Item[i].usConfidence);
    }
    return 0;
}
...