Calling Pocketsphinx in C# AccesViolationException

2019-05-11 18:58发布

问题:

I'm trying to do the pocketsphinx tutorial in C# using pinvoke but get an AccessViolationException when I try to decode using ps_decode_raw().

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

The functions are wrapped as follows

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

I wrapped C's fopen as well just because it was the quickest way I can think of implementing the tutorial.

I tried calling cmd_ln_retain on ps to make sure that ps wasn't causing the problem. (it wasn't). I also removed my debug code in the above.

I'm pretty sure something is up with the fopen but I'm not sure what.

Someone asked for the pocketsphinx log. https://justpaste.it/h52t

回答1:

You don't check for errors anywhere. And it's wrong to set SetLastError to true for these functions. They won't call SetLastError.

Your big problem though is that the library uses a particular instance of the C runtime, depending on how you built it. And your fopen import is from a different instance of the C runtime.

You'll need to add some code to the library that exposes functions to create and destroy FILE* objects. By doing that you'll get a FILE* made by the correct runtime.