1

目标:

获取包装 dll 以在 Windows 的 Unity 项目中使用 pocketsphinx。

问题:

System.DllNotFoundException运行测试程序时,即使 .so 文件与单声道程序位于同一目录中,我也会感到很烦人。

设置和尝试的操作:

首先,我使用的是 Cygwin。我能够构建任何东西,sphinxbase 和 pocketsphinx 没问题。然后我进入 swig/csharp 目录并尝试 make。它确实会创建一个 .so 文件。我正在使用默认的 Makefile 并在 cygwin 中制作。规则 1-3 运行得非常好,构建、链接和一切。pocketsphinx_continuous 测试也是如此。

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

尝试时mono test.exe- 会发生以下情况:

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

.sotest.exe 文件位于同一目录中,并且肯定会被查看,因为使用 运行 mono 时MONO_LOG_LEVEL=debug,输出为:

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

一遍又一遍。

任何帮助将不胜感激。同样,我需要一个 libpocketsphinx.so x86_64 用于 Unity 中的 Windows,以便与 C# 文件进行互操作。

谢谢。

--- 编辑 - 添加了相关的片段。test.cs 只是从包装数据结构中调用此方法。这些文件都是由 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);
4

2 回答 2

1

我怀疑 Cygwin DLL 是否与 Mono/Unity 兼容。您需要在 Visual Studio 中创建 DLL,然后它才能工作。

于 2017-08-06T06:10:27.830 回答
0

为什么你用单声道测试so文件,而它实际上是在Unity中使用的?

Mono: DllImport error loading library 'C:\Users\fgera\Development\Tools\CMUSphinx\pocketsphinx\swig\csharp\libpocketsphinxwrap.so.dll': '系统找不到指定的文件。

如果文件libpocketsphinxwrap.so确实存在于 中C:\Users\fgera\Development\Tools\CMUSphinx\pocketsphinx\swig\csharp\,请尝试重命名libpocketsphinxwrap.solibpocketsphinxwrap.so.dll以便 mono 可以找到它。

另请参阅mono pinvoke:库名称DllNotfoundException


您可以尝试使用 Visual Studio 构建 pocketsphinx,因为它是官方支持的。

顺便说一句,我宁愿自己编写 C# 包装器而不是使用 SWIG,因为 P/Invoke 中有很多陷阱,而且我认为 SWIG 不能处理所有这些陷阱。

于 2017-08-06T05:28:52.550 回答