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

发布于 2024-10-16 01:04:05 字数 1711 浏览 4 评论 0原文

我遇到了一种情况,我正在单步执行非/托管代码,并且我认为我的方法导致我收到“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."

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

I have a situation where I am stepping in and out of un/managed code, and I think my methodology is causing me to get a "FatalExecutionEngineError". Specifically, I have a C# callback ("X") which returns another callback ("Y") into C#, where both X and Y are called by unmanaged C++ code (which is called by C#). The error is thrown when returning from callback Y.


Dll Import Statements:

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

The unmanaged C code:

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;
    }
}

Delegate definitions:

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

The error message:

"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."

The code works some of the time (and worked just fine before I added the nested callbacks), but throws this exception the rest of the time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ζ澈沫 2024-10-23 01:04:06

代表们通常使用 fastcall。但是c风格的函数指针使用cdecl。使用 UnamangedFuntionPointer 属性标记您的委托。

Delegates generally use fastcall. But c style function pointers use cdecl. Tag your delegate with the UnamangedFuntionPointer-attribute.

南七夏 2024-10-23 01:04:06

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

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

I'm unsure of exactly what you're doing, but there are two causes I can think of. I'm assuming you've converted the delegate to a function pointer. Then...

  • You must ensure that the delegate object is not garbage collected. The GC doesn't see your function pointer, so it'll clean up the delegate pronto. There are a few handle handle-containers in namespace msclr, but if you're dealing with a complex scenario you may need to manually allocate GCHandle. Of course, you may already be doing this ;-).
  • You must further ensure that the reference to the GC-controlled object isn't moved while you access it. pin_ptr is one way to do that locally, but you sound like your passing things around in a complicated fashion, so that may mean you need to manually pin an object, with GCHandle.Alloc(..., GCHandleType.Pinned)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文