Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从回调调用非托管代码时,应如何返回委托?_C#_C++_Delegates_Unmanaged_Dllimport - Fatal编程技术网

C# 从回调调用非托管代码时,应如何返回委托?

C# 从回调调用非托管代码时,应如何返回委托?,c#,c++,delegates,unmanaged,dllimport,C#,C++,Delegates,Unmanaged,Dllimport,我遇到了这样一种情况:我正在进出un/托管代码,我认为我的方法使我得到了一个“FatalExecutionEngineError”。具体来说,我有一个C回调(“x”),它将另一个回调(“y”)返回到C,其中X和Y都是用非托管C++代码调用的(C调用)。从回调Y返回时引发错误 Dll导入语句: [DllImport ("SearchDLL.dll", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe

我遇到了这样一种情况:我正在进出un/托管代码,我认为我的方法使我得到了一个“FatalExecutionEngineError”。具体来说,我有一个C回调(“x”),它将另一个回调(“y”)返回到C,其中X和Y都是用非托管C++代码调用的(C调用)。从回调Y返回时引发错误


Dll导入语句:

[DllImport ("SearchDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe bool Dll_Search_Text (..., delegate_add_result Fn);

非托管C代码:

extern "C" {
__declspec(dllexport) bool Dll_Search_Text (..., bool (*Add_Result (int, int)) (int, int, int)) {
    bool (*Add_Result_Word) (int, int, int);
    bool Add_Word_Ret;

    ...    
    Add_Result_Word = Add_Result ([int param], [int param]);
    if (0 == Add_Result_Word) return false;
    ...

        for (Itr=Set->begin (); Itr != Set->end (); Itr++) {
            ...
            Add_Word_Ret = Add_Result_Word ([int param], [int param], [int param]);   
            }
        }

    return true;
    }
}

代表定义:

public delegate bool delegate_add_result_word (int A, int B, int C);
public delegate delegate_add_result_word delegate_add_result (int D, int E);

错误消息:

"Managed Debugging Assistant 'FatalExecutionEngineError' has detected a
problem in 'C:\Neuric\bin\Search.exe'. Additional Information: The 
runtime has encountered a fatal error. The address of the error was
at 0x6ea2ceca, on thread 0x744. The error code is 0xc0000005. This 
error may be a bug in the CLR or in the unsafe or non-verifiable 
portions of user code. Common sources of this bug include user marshaling
errors for COM-interop or PInvoke, which may corrupt the stack."


代码在某些时候可以工作(在我添加嵌套回调之前工作得很好),但在其余时间会抛出此异常。

代理通常使用fastcall。但是c风格的函数指针使用cdecl。使用unamangedFunctionPointer属性标记您的代理。

代理通常使用fastcall。但是c风格的函数指针使用cdecl。用unamangedFunctionPointer属性标记您的代理。

我不确定您到底在做什么,但我可以想到两个原因。我假设您已将委托转换为函数指针。然后

  • 必须确保委托对象未被垃圾收集。GC没有看到您的函数指针,因此它会立即清理委托。命名空间msclr中有几个句柄容器,但是如果您正在处理复杂的场景,则可能需要手动分配
    GCHandle
    。当然,您可能已经在这样做了;-)
  • 您必须进一步确保在访问GC受控对象时不会移动对该对象的引用
    pin_ptr
    是在本地实现这一点的一种方法,但听起来像是在以复杂的方式传递东西,因此这可能意味着您需要使用
    • 我不确定你到底在做什么,但我能想到两个原因。我假设您已将委托转换为函数指针。然后

      • 必须确保委托对象未被垃圾收集。GC没有看到您的函数指针,因此它会立即清理委托。命名空间msclr中有几个句柄容器,但是如果您正在处理复杂的场景,则可能需要手动分配
        GCHandle
        。当然,您可能已经在这样做了;-)
      • 您必须进一步确保在访问GC受控对象时不会移动对该对象的引用
        pin_ptr
        是在本地实现这一点的一种方法,但听起来像是在以复杂的方式传递东西,因此这可能意味着您需要使用

      哈哈!我知道是这样的,但我不知道如何给它贴上这样的标签。非常感谢。现在可以了^__^@阿曼杜,别忘了为答案投票,并将最好的答案标记为答案。@Eamon Nerbonne,噢,谢谢。这是我第二次问问题。哈哈!我知道是这样的,但我不知道如何给它贴上这样的标签。非常感谢。现在可以了^__^@阿曼杜,别忘了为答案投票,并将最好的答案标记为答案。@Eamon Nerbonne,噢,谢谢。这只是我第二次问问题。如何将.NET委托转换为C函数指针,以及如何处理函数指针/委托以支持转换?架构是什么x86或x64?如何将.NET委托转换为C函数指针,为了支持转换,您对函数指针/委托做了什么?x86或x64的体系结构是什么?我一直担心这种情况(但同样,不确定解决方法是什么),但使用您提供的信息,我发现:委托似乎不会被移动,但我还是要想办法“延长代表的寿命”。我应该能够在我的托管类中添加对委托的引用,不是吗?谢谢链接!实际上,托管类中的引用应该很好,只要该类本身在某处引用,即;-)。我一直在担心这种情况(但同样,不确定解决方法到底是什么),但根据您给我的信息,我发现了这一点:代理似乎不会被移动,但我仍然必须找到“延长代理寿命”的方法。我应该能够在我的托管类中添加对委托的引用,不是吗?谢谢链接!实际上,托管类中的引用应该很好,只要该类本身在某处引用,即;-)。