使用IntPtr从非托管cpp到托管c#的嵌套结构处理

时间:2018-09-19 10:10:41

标签: c# c++ struct intptr

我正在尝试将值分配给托管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;
}

0 个答案:

没有答案