我正在构建一个围绕C dll用C#编写的COM包装器,当我调用一个引用预先初始化的结构数组的特定函数时出现错误。
错误是:“sXEposCOM.dll中出现'System.ExecutionEngineException类型'的未处理异常”
C函数的签名如下:
UINT16 sXGetSupportedSchemes( SXEposScheme_t *pSchemes );
C dll中的SXEposScheme_t结构声明为:
typedef struct _SXEposScheme_t
{
BYTE schemeID[SX_EPOS_SID_LENGTH];
char schemeName[SX_EPOS_MAX_SCHEME_NAME_LENGTH];
} SXEposScheme_t;
在我的C#包装器(sXEposCOM)中,我有以下内容:
private const int SX_EPOS_SID_LENGTH = 2;
private const int SX_EPOS_MAX_NUM_SCHEMES = 10;
[DllImport("SXEposDll.dll")]
private static extern UInt16 sXGetSupportedSchemes(ref SXEposScheme_t [] pSchemes);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SXEposScheme_t
{
[MarshalAs(
UnmanagedType.ByValArray,
SizeConst = SX_EPOS_SID_LENGTH)]
public byte[] schemeID;
[MarshalAs(
UnmanagedType.ByValArray,
SizeConst = SX_EPOS_MAX_SCHEME_NAME_LENGTH)]
public char [] schemeName;
}
public int GetSupportedSchemes()
{
uint result = 0;
uint schemeCnt = 0;
GetNumSchemes(ref schemeCnt); //This call to the C dll succeeds and returns 2 to schemeCnt
SquidEposScheme_t[] schemes = new SXEposScheme_t[schemeCnt];
result = sXGetSupportedSchemes(ref schemes); //Errors on this line with An unhandled exception of type 'System.ExecutionEngineException occurred in sXEposCOM.dll
...
...
return result;
}
有谁能告诉我为什么会收到此错误?
答案 0 :(得分:1)
当本机代码破坏垃圾收集堆时会触发此异常。这里有很多机会,你的C#声明看起来不对。数组已作为指针传递,将 ref 添加到参数使其成为指针的指针。可能的解决方法:
[DllImport("SXEposDll.dll")]
private static extern UInt16 sXGetSupportedSchemes([In,Out] SXEposScheme_t [] pSchemes);
Pack = 1非常不合适,使用ByValTStr编组一个字符串。可能的解决方法:
[StructLayout(LayoutKind.Sequential)]
public struct SXEposScheme_t
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SX_EPOS_SID_LENGTH)]
public byte[] schemeID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = SX_EPOS_MAX_SCHEME_NAME_LENGTH)]
public string schemeName;
}