1

Goal:

Obtain a wrapper dll to use pocketsphinx in a Unity project in Windows.

Problem:

When running the test program, I get an annoying System.DllNotFoundException even though the .so file is in the same directory as the mono program.

Setup and attempted actions:

For starters, I am using Cygwin. I was able to build absolutely everything, sphinxbase and pocketsphinx no problem. Then I went into the swig/csharp directory and attempted make. It does make, a .so file is created. I am using the default Makefile and make in cygwin. Rules 1-3 run perfectly fine, building, linking and everything. So does the pocketsphinx_continuous test.

pocketsphinx.c: ../pocketsphinx.i
    mkdir -p gen
    swig -I.. -I../../../sphinxbase/swig -I../include -I../../sphinxbase/include \
        -csharp \
        -dllimport "libpocketsphinxwrap.so" \
        -namespace "Pocketsphinx" -o sphinxbase.c \
        -outdir gen ../../../sphinxbase/swig/sphinxbase.i
    swig -I.. -I../../../sphinxbase/swig -I../include -I../../sphinxbase/include \
        -csharp \
        -dllimport "libpocketsphinxwrap.so" \
        -namespace "Pocketsphinx" -o pocketsphinx.c \
        -outdir gen ../pocketsphinx.i

libpocketsphinxwrap.so: pocketsphinx.c
    gcc -fPIC pocketsphinx.c sphinxbase.c `pkg-config --libs --cflags pocketsphinx` -shared -o $@

test.exe: libpocketsphinxwrap.so
    mcs test.cs gen/*.cs

run: test.exe
    MONO_LOG_LEVEL=debug mono test.exe

clean:
    rm -rf gen
    rm -f libpocketsphinxwrap.so
    rm -f pocketsphinx.c
    rm -f sphinxbase.c
    rm -f test.exe

.PHONY: run clean

When attempting mono test.exe - the following happens:

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'Pocketsphinx.PocketSphinxPINVOKE' threw an exception. ---> System.TypeInitializationException: The type initializer for 'SWIGExceptionHelper' threw an exception. ---> System.DllNotFoundException: libpocketsphinxwrap.so

The .so is in the same directory as the test.exe file and is certainly being looked at because when running mono with MONO_LOG_LEVEL=debug, the output is:

Mono: DllImport error loading library 'C:\Users\fgera\Development\Tools\CMUSphinx\pocketsphinx\swig\csharp\libpocketsphinxwrap.so.dll': 'The system cannot find the file specified.

Many times over and over.

Any help will be greatly appreciated. Again, I need a libpocketsphinx.so x86_64 for windows in Unity to interop with the C# files.

Thanks.

--- edit - added relevant snippet. test.cs just calls this method from the wrapper data structure. These files were all generated by SWIG.

  [global::System.Runtime.InteropServices.DllImport("libpocketsphinxwrap.so", EntryPoint="CSharp_Pocketsphinx_Decoder_GetConfig")]
  public static extern global::System.IntPtr Decoder_GetConfig(global::System.Runtime.InteropServices.HandleRef jarg1);
Fer
  • 460
  • 2
  • 4
  • 17
  • You'd better test it by building a real Unity project instead of using mono. They are different. – zwcloud Aug 06 '17 at 05:10
  • @zwcloud I get the same error in Unity. Unity uses mono as well. It should work in both. – Fer Aug 06 '17 at 12:49
  • Again.. please edit your question and post the content of test.cs: let's see how you define the extern method with attribute `DllImport`. – zwcloud Aug 06 '17 at 12:52
  • posted @zwcloud , the definitions were generated from a .i file by SWIG. – Fer Aug 06 '17 at 12:58

2 Answers2

1

I doubt Cygwin DLL is compatible with Mono/Unity. You need to create DLL in Visual Studio, then it will work.

Nikolay Shmyrev
  • 24,897
  • 5
  • 43
  • 87
  • How could it now be if I am building the source with gcc natively on my machine and when inspected with dumpbin on the Visual Studio console if can read all the segments? – Fer Aug 06 '17 at 12:48
0

Why do you test the so file with mono, while it is actually used in Unity?

Mono: DllImport error loading library 'C:\Users\fgera\Development\Tools\CMUSphinx\pocketsphinx\swig\csharp\libpocketsphinxwrap.so.dll': 'The system cannot find the file specified.

If file libpocketsphinxwrap.so does exist in C:\Users\fgera\Development\Tools\CMUSphinx\pocketsphinx\swig\csharp\, try rename libpocketsphinxwrap.so to libpocketsphinxwrap.so.dll so mono can find it.

See also mono pinvoke: library names and DllNotfoundException.


You can try build pocketsphinx with Visual Studio since it is offically supported.

BTW, I'd rather write the C# wrapper myself instead of using SWIG since there are many traps in P/Invoke and I don't think SWIG can handle all of them.

zwcloud
  • 4,546
  • 3
  • 40
  • 69
  • Unity runs on mono. I am compiling the source with gcc on a x86_64 machine and I am not forcing -m32 flag on it. When I try the file on Unity, I get the same error. I read everything you quote already. Thanks. – Fer Aug 06 '17 at 12:46
  • I should say Unity runs on a modified ancient mono. But yes, if your so file works on mono, it probably works on Unity. – zwcloud Aug 06 '17 at 12:47
  • Thanks. I did try .so, dll no name... on the DEBU output, mono tries all possible extensions with no luck. – Fer Aug 06 '17 at 13:40