P / Invoke抛出System.ExecutionEngineException

时间:2009-12-02 14:49:48

标签: c# pinvoke executionengineexception

我有一个用C ++编码的封闭源非托管DLL我想在C#解决方案中使用,所以我创建了一个使用P / Invoke来调用封闭源DLL函数的包装器托管DLL。对于没有param函数和int变量,这非常有效。但是,当运行一个更复杂的函数时,我得到一个System.ExecutionEngineException,该函数将一个struct数组作为参数,该参数包含字符串的char数组。这就是我所拥有的:

[StructLayout(LayoutKind.Sequential)]
public struct Target
{
    public int targetID;

    public string Label;
}

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTarget")]
public static extern int GetTarget(ref Target[] targets);

以下是我从DLL的头文件中获得的信息:

#define TARGET_LBL_SIZE   (256l)

typedef struct _tyrfdeTarget
{
    TInt32 TargetID;                   // integer signed 32bits
    TCharA Label[TARGET_LBL_SIZE];     // caracter
} tyrfdeTarget;

TInt32 __stdcall tyrfdeGetTargets(tyrfdeTarget* pTargets);

不太确定为什么数组大小指定为long,但无论如何SizeConst只接受int。经过一些搜索,这是我试图解决的问题。

[StructLayout(LayoutKind.Sequential, Size = 260), Serializable]
public struct Target
{
    public int targetID;

    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string Label;
}

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTargets")]
public static extern int GetTarget(ref Target[] targets);

但我仍然有问题。我已经读过,如果函数清除了CLR使用的内存的一部分,则会抛出此异常。不幸的是我无法验证。我的代码中是否存在明显错误并可能导致问题的内容?

2 个答案:

答案 0 :(得分:2)

嗯,我认为您的问题在于参考Target[] targets参数。 AFAIR这是对参考的引用,这可能不是你真正想要的。

我试试这个:

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTargets")]
public static extern int GetTarget([Out, MarshalAs(UnmanagedType.LPArray)] Target[] targets);

也许this article可以帮助您找到正确的声明。

请注意,此处的数组大小不明确,通常在这种情况下还会有ref int length参数,然后可以通过MarshalAsSizeParameterIndex属性中引用该参数属性。

答案 1 :(得分:0)

1)你确定TCharA是16位吗?否则我认为你还应该指定使用whar CharSet。

2)在C ++ / CLI中编写这种包装器更简单。