将值分配给从非托管cpp调用的c#中的地址用户定义结构
Assigning values to the address user defined structure in c# called from unmanaged cpp
考虑以下结构
/*Structure defined in unmanaged dll written in cpp*/
struct NSCASR_RCG_RES_ST
{
unsigned int ulSizeBytes;
unsigned int ulWarnings;
unsigned short usNumPhrases;
wchar_t* pstrWaveformURI;
unsigned int ulWaveformSizeBytes;
unsigned int ulWaveformDuration;
};
/*Structure defined in c#*/
struct NSCASR_RCG_RES_ST
{
unsigned int ulSizeBytes;
unsigned int ulWarnings;
unsigned short usNumPhrases;
String pstrWaveformURI;
unsigned int ulWaveformSizeBytes;
unsigned int ulWaveformDuration;
};
在我的 unmagaed DLL(cpp) 中,我通过传递结构地址来调用函数,如下所示:
NSCASR_RCG_RES_ST result_recognize;
ASR_Recognize_ResultsGet(&result_recognize);
在我的托管 DLL 中,定义类似于
void ASR_Recognize_ResultsGet(NSCASR_RCG_RES_ST *recognize)
{
/*MRCP_MD_TO_ASR is namespace and Constants is class name
which consists of structure NSCASR_RCG_RES_ST */
MRCP_MD_TO_ASR::Constants::NSCASR_RCG_RES_ST *pRecognitionResults;
pRecognitionResults = (MRCP_MD_TO_ASR::Constants::NSCASR_RCG_RES_ST *)recognize;
MRCP_MD_TO_ASR::ASR_API::ASR_Recognize_ResultsGet(*pRecognitionResults);
}
在 c# 代码中,我分配了以下成员
public static int ASR_Recognize_ResultsGet(ref Constants.NSCASR_RCG_RES_ST pRecognitionResults)
{
pRecognitionResults = speech_results;
pRecognitionResults.ulSizeBytes = 200;
return 0;
}
但是当我在语句执行后看到result_recognize的内容时
值 200 被分配给 usNumPhrases 变量而不是 ulSizeBytes
我通过显式添加 structlayout 并使用 charset 获得了解决方案,因为 c# 使用 unicode 16,如果我们使用 IntPtr 概念,我们必须将其设置为 unicode 8
[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;
}
[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;
}
考虑以下结构
/*Structure defined in unmanaged dll written in cpp*/
struct NSCASR_RCG_RES_ST
{
unsigned int ulSizeBytes;
unsigned int ulWarnings;
unsigned short usNumPhrases;
wchar_t* pstrWaveformURI;
unsigned int ulWaveformSizeBytes;
unsigned int ulWaveformDuration;
};
/*Structure defined in c#*/
struct NSCASR_RCG_RES_ST
{
unsigned int ulSizeBytes;
unsigned int ulWarnings;
unsigned short usNumPhrases;
String pstrWaveformURI;
unsigned int ulWaveformSizeBytes;
unsigned int ulWaveformDuration;
};
在我的 unmagaed DLL(cpp) 中,我通过传递结构地址来调用函数,如下所示:
NSCASR_RCG_RES_ST result_recognize;
ASR_Recognize_ResultsGet(&result_recognize);
在我的托管 DLL 中,定义类似于
void ASR_Recognize_ResultsGet(NSCASR_RCG_RES_ST *recognize)
{
/*MRCP_MD_TO_ASR is namespace and Constants is class name
which consists of structure NSCASR_RCG_RES_ST */
MRCP_MD_TO_ASR::Constants::NSCASR_RCG_RES_ST *pRecognitionResults;
pRecognitionResults = (MRCP_MD_TO_ASR::Constants::NSCASR_RCG_RES_ST *)recognize;
MRCP_MD_TO_ASR::ASR_API::ASR_Recognize_ResultsGet(*pRecognitionResults);
}
在 c# 代码中,我分配了以下成员
public static int ASR_Recognize_ResultsGet(ref Constants.NSCASR_RCG_RES_ST pRecognitionResults)
{
pRecognitionResults = speech_results;
pRecognitionResults.ulSizeBytes = 200;
return 0;
}
但是当我在语句执行后看到result_recognize的内容时 值 200 被分配给 usNumPhrases 变量而不是 ulSizeBytes
我通过显式添加 structlayout 并使用 charset 获得了解决方案,因为 c# 使用 unicode 16,如果我们使用 IntPtr 概念,我们必须将其设置为 unicode 8
[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;
}
[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;
}