3

我正在尝试使用 pinvoke 在 C# 中完成 pocketsphinx教程,但是当我尝试使用 ps_decode_raw() 进行解码时得到 AccessViolationException。

        IntPtr ps = PocketSphinx.ps_init(config);
        IntPtr fh = Win32Util.fopen(@"goforward.raw", "rb");
        int rv = PocketSphinx.ps_decode_raw(ps, fh, "goforward", -1);

函数包装如下

    //ps_decoder_t* ps_init(cmd_ln_t* config)
    [DllImport("pocketsphinx.dll",
        SetLastError = true,
        CallingConvention = CallingConvention.Cdecl)]
    public extern static IntPtr ps_init(
        IntPtr config);

    //int ps_decode_raw(ps_decoder_t *ps, FILE *rawfh, char const *uttid, long maxsamps);
    [DllImport("pocketsphinx.dll",
        SetLastError = true,
        CallingConvention = CallingConvention.Cdecl)]
    public extern static int ps_decode_raw(
        IntPtr ps,
        IntPtr rawfh,
        [MarshalAs(UnmanagedType.LPStr)] string uttid,
        int maxsamps);

    [DllImport("msvcrt.dll",
        SetLastError = true,
        CallingConvention = CallingConvention.Cdecl)]
    public extern static IntPtr fopen(
        [MarshalAs(UnmanagedType.LPStr)] string _Filename,
        [MarshalAs(UnmanagedType.LPStr)] string _Mode);

我也包装了 C 的 fopen 只是因为它是我能想到的实现本教程的最快方式。

我尝试在 ps 上调用 cmd_ln_retain 以确保 ps 没有导致问题。(不是)。我还删除了上面的调试代码。

我很确定 fopen 出了点问题,但我不确定是什么。

有人要pocketsphinx日志。https://justpaste.it/h52t

4

1 回答 1

2

您不会在任何地方检查错误。并且将SetLastError这些函数设置为 true 是错误的。他们不会打电话SetLastError的。

不过,您的大问题是该库使用 C 运行时的特定实例,具体取决于您构建它的方式。您的fopen导入来自 C 运行时的不同实例。

您需要向库中添加一些代码,以公开创建和销毁FILE*对象的函数。通过这样做,您将获得FILE*正确的运行时制作。

于 2014-09-18T05:42:06.463 回答