在C#AccesViolationException中调用Pocketsphinx
我试图使用pinvoke在C#中执行pocketsphinx,但当我尝试使用ps_decode#u raw()进行解码时,会出现AccessViolationException 函数包装如下在C#AccesViolationException中调用Pocketsphinx,c#,c,pinvoke,pocketsphinx-android,C#,C,Pinvoke,Pocketsphinx Android,我试图使用pinvoke在C#中执行pocketsphinx,但当我尝试使用ps_decode#u raw()进行解码时,会出现AccessViolationException 函数包装如下 //ps_decoder_t* ps_init(cmd_ln_t* config) [DllImport("pocketsphinx.dll", SetLastError = true, CallingConvention = CallingConventio
//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出了什么问题,但我不确定是什么问题
有人要了Pocketsphenx的日志 您不会在任何地方检查错误。对于这些函数,将
SetLastError
设置为true是错误的。他们不会调用SetLastError
不过,最大的问题是库使用了一个特定的C运行时实例,这取决于构建它的方式。您的fopen
导入来自C运行时的另一个实例
您需要向库中添加一些代码,以公开创建和销毁
文件*
对象的函数。通过这样做,您将得到一个由正确的运行时生成的文件*
看到标准输出(日志)上的pocketsphinx输出添加到日志的链接会很有帮助。我将删除pInvoker添加的SetLastError
。我不知道如何测试C运行时是否正确。DLL是system32文件夹中的DLL。我还包装了fgets()
以检查它是否是文件*
,它的工作让我更加不知所措。我将尝试包装fseek()
,看看这是否会导致下一步出现任何问题。你只会让事情变得更糟。当然,当从系统msvcrt传递一个用fopen
创建的文件*
时,系统msvcrt的其他功能也可以正常工作。这证明不了什么。问题是您的pocketsphinx.dll
没有使用系统msvcrt。它使用MSVC中的运行时来构建DLL。你为什么不照我说的做呢?我不得不用它来发现pocketsphinx是用MSVCR100D.DLL而不是msvcrt.DLL编译的,现在它可以工作了。还有比这更多的东西。无法重新分发调试运行时。所以,一旦你想重新发布它,你就需要切换到发布版本,然后你就会回到你现在的位置。解决这个问题的聪明方法正是我在最后一段中所说的。添加到pocketsphinx.dll中,以生成所需运行时函数的一些导出。
//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);