在C#AccesViolationException中调用Pocketsphinx

我正在尝试使用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); 

function包括如下

  //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会有什么问题,但我不确定是什么。

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

您不会在任何地方检查错误。 将这些函数的SetLastError设置为true是错误的。 他们不会调用SetLastError

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

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