c# - 为什么我在调用 DllImport 之前中断时会得到 AccessViolationException?

标签 c# .net visual-studio-2010 debugging pinvoke

我正在尝试在 C# 中使用来自非托管 DLL 的 C 函数。

函数的签名是:

const char*  CDECL get_lame_version       ( void );

我这样导入函数:

[DllImport("libmp3lame.dll")]
static extern string get_lame_version();

如果我调用此函数,但我在调用前中断,然后按 F5,则会抛出 AccessViolationException。

首先,执行在调用之前中断:

here the execution breaks just before the call

然后我按F5,出现异常:

AccessViolationException

如果执行在调用之后中断,则不会抛出异常:

enter image description here

所以我的问题是:我的代码有什么问题吗?如果不是,那是怎么回事?

编辑

这里是 get_lame_version 的定义:

/*! Get the LAME version string. */
/*!
  \param void
  \return a pointer to a string which describes the version of LAME.
*/
const char *
get_lame_version(void)
{                       /* primary to write screen reports */
    /* Here we can also add informations about compile time configurations */

#if   LAME_ALPHA_VERSION
    static /*@observer@ */ const char *const str =
        STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " "
        "(alpha " STR(LAME_PATCH_VERSION) ", " __DATE__ " " __TIME__ ")";
#elif LAME_BETA_VERSION
    static /*@observer@ */ const char *const str =
        STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " "
        "(beta " STR(LAME_PATCH_VERSION) ", " __DATE__ ")";
#elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0)
    static /*@observer@ */ const char *const str =
        STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) "." STR(LAME_PATCH_VERSION);
#else
    static /*@observer@ */ const char *const str =
        STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION);
#endif

    return str;
}

最佳答案

pinvoke 签名错误。应该是:

[DllImport("libmp3lame.dll", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr get_lame_version();

要调用它,您需要这样做;

string version = Marshal.PtrToStringAnsi(get_lame_version());

您不能依赖 p/invoke 编码器来编码字符串值,因为它不拥有该字符串。 DLL 拥有该字符串。

此外,您应该为 LAME DLL 函数指定调用约定,否则您最终将使用默认的 pinvoke 调用约定 stdcall。对于没有参数的函数来说这无关紧要,但这是一个养成的好习惯。

关于c# - 为什么我在调用 DllImport 之前中断时会得到 AccessViolationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10313287/

相关文章:

java - CUCM 8.5 AXLAPI 中的示例 doAuthenticateUser 请求消息

C# 在 xml 中合并命名空间引用

c# - ASP.NET 文件上传

c# - 缩放 SKImage (SkiaSharp) 的最快方法

.net - 一对一的可选关系,两端可选且两个 FK

c++ - 在 Microsoft Visual Studio 2010 中添加 .lib 文件

c# - 使用单个接口(interface)注册多个实现

.net - 异步和 .NET 事件?

c# - 在文本框中显示 ListView 的值

visual-studio-2010 - 如何在 xml 格式的 resx 文件中添加条件编译?