P/Invoke throw System.ExecutionEngineException

情到浓时终转凉″ 提交于 2019-12-22 00:35:48

问题


I have a closed source unmanaged DLL coded in C++ that I wanted to use in a C# solution so I created a wrapper managed DLL that use P/Invoke to call the closed source DLL function. That works pretty well for no param function and int variables. However I get a System.ExecutionEngineException when running a more complex function that take an array of struct as parameter which contains array of char for strings. Here is what I had:

[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);

Below is the information I have from the header file of the 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);

Not quite sure why the array size is specified as long but anyway SizeConst only take int. After some search here is what I tried to fix.

[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);

But I still have the problem. I have read that this exception can throw if the functions clear part of the memory used by CLR. Unfortunately I cannot verify that. Is there something in my code that is obviously wrong and could cause the problem?


回答1:


Hm, I think your problem is with the ref Target[] targets parameter. AFAIR this is a reference to a reference, which is probably not what you actually want.

I'd try this:

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

Maybe this article helps you to find the correct declaration.

Note that the size of the array is not clear here, usually in such cases there is also a ref int length parameter, which can then be referenced in the MarshalAs attribute via the SizeParameterIndex property.




回答2:


1) Are you sure that TCharA is 16-bit? Otherwise I think you should also specify whar CharSet to use.

2) Writing this kind of wrappers is way way simpler in C++/CLI.



来源:https://stackoverflow.com/questions/1833368/p-invoke-throw-system-executionengineexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!