C# 为什么在调用DllImport之前中断时会收到AccessViolationException?

C# 为什么在调用DllImport之前中断时会收到AccessViolationException?,c#,.net,visual-studio-2010,debugging,pinvoke,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 首先,执行在调用之前中断: 然后按F5,出现异常: 如果调

我试图使用C#中非托管DLL中的C函数

该函数的签名为:

const char*  CDECL get_lame_version       ( void );
我通过以下方式导入函数:

[DllImport("libmp3lame.dll")]
static extern string get_lame_version();
如果调用此函数,但在调用之前中断,然后按F5,则会引发AccessViolationException

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

然后按F5,出现异常:

如果调用后执行中断,则不会引发异常:

所以我的问题是:我的代码有什么问题吗?如果没有,发生了什么

编辑

以下是get_lame_版本的定义:

/*! 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;
}

访问冲突是由非托管代码引起的,而不是您的C#代码。如果不看到非托管代码,很难说出问题所在。

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
。对于一个没有参数的函数来说,这并不重要,但这是一个好习惯。

我添加了函数的定义。有关如何具体处理函数返回字符时返回字符串的互操作的建议,请参阅和。我通常不会给出这样的注释,但非常感谢您的回答!