2

C#でアンマネージDLLのC関数を使用しようとしています。

関数のシグネチャは次のとおりです。

const char*  CDECL get_lame_version       ( void );

この方法で関数をインポートします。

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

この関数を呼び出したが、呼び出しの直前に中断した場合、F5キーを押すと、AccessViolationExceptionがスローされます。

まず、呼び出しの直前に実行が中断されます。

ここでは、呼び出しの直前に実行が中断されます

次にF5を押すと、例外があります。

AccessViolationException

代わりに、呼び出し後に実行が中断した場合、例外はスローされません。

ここに画像の説明を入力してください

だから私の質問は:私のコードに何か問題がありますか?そうでない場合、何が起こっていますか?

編集

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

2 に答える 2

1

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. これは、パラメーターのない関数には関係ありませんが、慣れるには良い習慣です。

于 2012-04-25T11:40:33.537 に答える
0

アクセス違反は、C# コードではなく、アンマネージ コードが原因です。アンマネージ コードを見ずに、何が問題なのかを判断するのは非常に困難です。

于 2012-04-25T10:00:24.200 に答える