我正在尝试使用pinvoke在C#中执行Pocketsphinx tutorial,但是当我尝试使用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有问题,但是我不确定是什么。

有人问了口袋狮身人面像日志。 https://justpaste.it/h52t

最佳答案

您不会在任何地方检查错误。这些功能将SetLastError设置为true是错误的。他们不会呼叫SetLastError

但是,最大的问题是该库使用C运行时的特定实例,具体取决于您如何构建它。而且您的fopen导入来自C运行时的另一个实例。

您需要向库中添加一些代码,以暴露用于创建和销毁FILE*对象的函数。这样,您将获得由正确的运行时生成的FILE*

关于c# - 在C#AccesViolationException中调用Pocketsphinx,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25900923/

10-11 02:28