当使用PInvoke调用C++ DLL时出现AccessViolationException异常(cdecl调用约定问题?)

7

我已经花了一整天的时间研究这个问题,但仍然无法理解:

我有一个C# DLL,其中PInvokes调用了一个C++ DLL中的方法。在Debug模式下编译时,我没有遇到任何问题,但在Release模式下编译时,我会遇到AccessViolationException异常。通过谷歌搜索,我发现可能是由于不兼容的调用约定引起的。现在C#代码如下所示:

[return: MarshalAs(UnmanagedType.U1)]
[DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern Boolean AMethod(Int32 mode, byte frame);

而在C++中:

extern "C" {
     DLL_EXPORT bool AMethod(int mode, BYTE frame)
     {
      ...
     }
}

我已将C++项目设置为在VS2010中使用__cdecl调用约定进行编译,但我仍然遇到AccessViolationException错误,并且不知道还能做什么。需要注意的是,我的C++ DLL使用第三方DLL,我不知道它们使用什么调用约定。
任何帮助将不胜感激!
哦,我在开发机上没有遇到异常,只有在目标系统上才会出现。

4
你是否设置了C++项目以在Debug和Release版本中都使用__cdecl调用约定? - Frédéric Hamidi
你的 DLL 是否使用 ATL?如果是,尝试将 ATL 的 Use 设置为“Static Link to ATL”。 - João Augusto
1
你尝试过切换到__stdcall吗?我在使用pinvoke时从来没有用Cdecl调用约定取得好的运气,我总是使用__stdcall。 - Justin
1
@PNielsen,调用约定不具传染性,因此我认为外部依赖关系不是问题的罪魁祸首。我更担心DLL_EXPORT宏展开后会得到什么? - Frédéric Hamidi
1
好的,事实证明异常是由另一个原因引起的(我仍然没有发现),与指定的调用约定无关。感谢您的所有帮助,至少我在这个过程中学到了一些关于调用约定的知识,特别是从这个网站(如果有人遇到这个问题):http://www.unixwiz.net/techtips/win32-callconv.html。 - PNielsen
显示剩余2条评论
1个回答

0

尝试使用以下语句重新排序:

[DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern Boolean AMethod(Int32 mode, byte frame);

2
你的回答让我很感兴趣。重新排列方法属性如何解决提问者的问题? - Frédéric Hamidi
我也很好奇方法的重新排序如何解决这个问题。 - Mandrake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接