代码之家  ›  专栏  ›  技术社区  ›  baptiste

调用throw system.executionengineexception

  •  1
  • baptiste  · 技术社区  · 16 年前

    我有一个用C++编写的封闭源非托管DLL,我想在C语言解决方案中使用,所以我创建了一个包装器管理的DLL,它使用P/VoCKE调用封闭源DLL函数。对于没有参数函数和int变量来说,这是非常好的。但是,当运行一个更复杂的函数时,我会得到一个System.ExecutionEngineeException,该函数将结构数组作为参数,其中包含字符串的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 回复  |  直到 16 年前
        1
  •  2
  •   Lucero    16 年前

    嗯,我想你的问题是裁判 Target[] targets 参数。这是一个参考,可能不是你真正想要的。

    我会尝试这个:

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

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

    注意,这里数组的大小不清楚,通常在这种情况下 ref int length 参数,然后可以在 MarshalAs 属性通过 SizeParameterIndex 财产。

        2
  •  0
  •   Dan Byström    16 年前

    1)您确定TChara是16位的吗?否则,我认为您还应该指定要使用的字符集。

    2)在C++/CLI中编写这种包装器的方式比较简单。

    推荐文章