2014-09-17 3 views
3

Я пытаюсь сделать pocketsphinx tutorial в C#, используя pinvoke, но получаю AccessViolationException при попытке декодирования с помощью ps_decode_raw().Вызов Pocketsphinx в C# AccesViolationException

 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); 

Я завернул Кассиопеяне FOPEN, а только потому, что это самый быстрый способ, которым я могу думать о реализации учебника.

Я попытался вызвать cmd_ln_retain на ps, чтобы убедиться, что ps не вызывает проблемы. (это не так). Я также удалил свой код отладки в приведенном выше.

Я почти уверен, что что-то с фоуном, но я не уверен, что.

Кто-то попросил журнал карманов. https://justpaste.it/h52t

+0

Было бы полезно увидеть вывод pocketsphinx на stdout (журнал). –

+0

добавил ссылку на журнал. –

ответ

2

Вы ни в коем случае не проверяете наличие ошибок. И неправильно установить SetLastError в true для этих функций. Они не будут звонить SetLastError.

Ваша большая проблема заключается в том, что библиотека использует конкретный экземпляр среды выполнения C, в зависимости от того, как вы ее создали. И ваш импорт fopen происходит из другого экземпляра среды выполнения C.

Вам нужно будет добавить код в библиотеку, которая предоставляет функции для создания и уничтожения объектов FILE*. Делая это, вы получите FILE*, созданный с помощью правильной среды выполнения.

+0

Я удалю 'SetLastError', которые были добавлены pInvoker. Я не уверен, как проверить, правильно ли вы используете C-среду выполнения. DLL - это папка system32. Я также завернул 'fgets()', чтобы проверить, был ли он 'ФАЙЛ * ', и это сработало, оставив меня больше в убытке. Я попробую обернуть 'fseek()', чтобы узнать, не вызвало ли это каких-либо проблем. –

+1

Вы просто делаете это хуже. Конечно, другие функции из системы msvcrt хороши при передаче 'FILE *', созданного с помощью 'fopen' из системы msvcrt. Это ничего не доказывает. Проблема в том, что ваш 'pocketsphinx.dll' не использует систему msvcrt. Он использует среду выполнения из MSVC, которую вы использовали для создания библиотеки DLL. Почему ты не делаешь то, что я говорю? –

+0

Мне пришлось использовать [зависимый ходок] (http://www.dependencywalker.com/), чтобы узнать, что pocketsphinx компилируется с MSVCR100D.DLL NOT msvcrt.dll, и теперь он работает. –