简体   繁体   English

Xamarin OpenEars本机绑定在设备上不起作用,但在模拟器上起作用

[英]Xamarin OpenEars Native Binding Not working on Device but works on Simulator

I have been working on using OpenEars v2.03 iOS framework project in xamarin iOS Binding project. 我一直在xamarin iOS绑定项目中使用OpenEars v2.03 iOS框架项目。 Let me explain what i did so far,.I'm new to XCode, Xamarin and all this Binding things. 让我解释一下到目前为止我做了什么。我是XCode,Xamarin和所有这些Binding的新手。 This gonna be a big questions, so hold your breath… 这将是一个大问题,请屏住呼吸……

1) Build the OpenEars framework project in Xcode for Simulator. 1)在Xcode for Simulator中构建OpenEars框架项目。 Copied the “OpenEars” file from Framework/OpenEars.framework/Versions/Current/ and renamed to “ libOpenEars-i386.a Framework / OpenEars.framework / Versions / Current /复制了“ OpenEars”文件,并将其重命名为“ libOpenEars-i386.a

Likewise build the same library for iPhone 4s Device by connecting the device to Mac and chosen the target to my iPhone. 同样,通过将设备连接到Mac并选择目标到我的iPhone,为iPhone 4s设备构建相同的库。 Finally copied the generated OpenEars and renamed it to “ libOpenEars-armv7.a 最后复制生成的OpenEars,并将其重命名为“ libOpenEars-armv7.a

2) Using lipo command bundled the two file (libOpenEars-i386.a, libOpenEars-armv7.a) to a single file “libOpenEars.a” using the below command. 2)使用lipo命令,使用以下命令将两个文件(libOpenEars-i386.a,libOpenEars-armv7.a)捆绑为一个文件“ libOpenEars.a”。

lipo -create -output libOpenEars.a libOpenEars-i386.a libOpenEars-armv7.a 

3) Created a Binding project in Xamarin Studio and added the libOpenEars.a, it generates a libOpenEars.linkwith.cs automatically. 3)在Xamarin Studio中创建一个Binding项目并添加libOpenEars.a,它自动生成一个libOpenEars.linkwith.cs Below is the following code, 以下是以下代码,

using System;
using ObjCRuntime;

[assembly: LinkWith ("libOpenEars.a", LinkTarget.ArmV7 | LinkTarget.Simulator, SmartLink = true, ForceLoad = true, Frameworks="AudioToolbox AVFoundation", IsCxx=true, LinkerFlags = "-lstdc++")]

I tried changing the liker flags LinkerFlags = "-lstdc++ -lc++ -ObjC” and SmartLink=false. 我尝试过更改Liker标志LinkerFlags =“ -lstdc ++ -lc ++ -ObjC”和SmartLink = false。

4) My ApiDefinition file contain all interface for OpenEars, i just added only one interface here. 4)我的ApiDefinition文件包含OpenEars的所有接口,我在这里仅添加了一个接口。

[BaseType(typeof(NSObject))]
[Protocol]
interface OEEventsObserver
{
    [Wrap ("WeakDelegate")]
    OEEventsObserverDelegate Delegate { get; set; }

    [Export ("delegate", ArgumentSemantic.Assign), NullAllowed]
    NSObject WeakDelegate { get; set; }
}

5) Referenced the OpenEars.dll to my iOS sample project. 5)将OpenEars.dll引用到我的iOS示例项目。

6) Add the language model and acoustic model in the Binding library itself. 6)在绑定库本身中添加语言模型和声学模型。 (Even though it is not needed for dynamic Language model generation , i used the old OpenEars sample project from this OpenEars Xamarin git , i dind't used the new DynamicLanguageModel generator but modified the example for latest changes). (即使不需要动态语言模型生成,我也使用了OpenEars Xamarin git中的旧OpenEars示例项目,没有使用新的DynamicLanguageModel生成器,而是修改了示例以进行最新更改)。

View Controller: 视图控制器:

public partial class OpenEarsNewApiViewController : UIViewController
{
    OEEventsObserver observer;
    OEFliteController fliteController;
    OEPocketsphinxController pocketSphinxController;


    String pathToLanguageModel;
    String pathToDictionary;
    String pathToAcousticModel;

    String firstVoiceToUse;
    String secondVoiceToUse;

    static bool UserInterfaceIdiomIsPhone {
        get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; }
    }

    public void init()
    {
        try
        {
            observer = new OEEventsObserver();
            observer.Delegate = new OpenEarsEventsObserverDelegate (this);
            pocketSphinxController = new OEPocketsphinxController ();

            fliteController = new OEFliteController();

            firstVoiceToUse = "cmu_us_slt";
            secondVoiceToUse = "cmu_us_rms";

            pathToLanguageModel = NSBundle.MainBundle.ResourcePath + System.IO.Path.DirectorySeparatorChar + "OpenEars1.languagemodel";
            pathToDictionary = NSBundle.MainBundle.ResourcePath + System.IO.Path.DirectorySeparatorChar + "OpenEars1.dic";
            pathToAcousticModel = NSBundle.MainBundle.ResourcePath;
        }
        catch(Exception e) {
            Console.WriteLine ("Exception Message :"+e.Message);
            Console.WriteLine ("Inner Exception Mesage :"+e.InnerException.Message);
        }

    }

    public OpenEarsNewApiViewController (IntPtr handle) : base (handle)
    {
        init ();
    }

    #region Update

    public void UpdateStatus (String text)
    {
        txtStatus.Text = text;
    }

    public void UpdateText (String text)
    {
        txtOutput.Text = text;
    }

    public void UpdateButtonStates (bool hidden1, bool hidden2, bool hidden3, bool hidden4)
    {
        btnStartListening.Hidden = hidden1;
        btnStopListening.Hidden = hidden2;
        btnSuspend.Hidden = hidden3;
        btnResume.Hidden = hidden4;
    }

    public void Say (String text)
    {
        //fliteController.SaywithVoice (text, secondVoiceToUse);
    }

    public void StartListening ()
    {
        //pocketSphinxController.RequestMicPermission ();
        if (!pocketSphinxController.IsListening) {

            //NSString *correctPathToMyLanguageModelFile = [NSString stringWithFormat:@"%@/TheNameIChoseForMyLanguageModelAndDictionaryFile.%@",[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0],@"DMP"];


            pocketSphinxController.StartListeningWithLanguageModelAtPath (
                pathToLanguageModel,
                pathToDictionary,
                pathToAcousticModel,
                false
            );
        } else {
            new UIAlertView ("Notify !!","Already Listening",null,"OK","Stop").Show();

        }

    }

    public void StopListening ()
    {
        //pocketSphinxController.StopListening ();
    }

    public void SuspendRecognition ()
    {
        pocketSphinxController.SuspendRecognition ();
    }

    public void ResumeRecognition ()
    {
        pocketSphinxController.ResumeRecognition ();
    }

    #endregion

    #region Event Handlers

    partial void btnStartListening_TouchUpInside (UIButton sender)
    {
        try
        {
            StartListening();
            //fliteController.Init();
            //Console.WriteLine("Speech in Progress :"+fliteController.SpeechInProgress);
            //fliteController.Say("Hai", new OEFliteVoice());

            UpdateButtonStates (true, false, false, true);
            Console.WriteLine("Speech in Progress :"+fliteController.SpeechInProgress);
        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    partial void btnStopListening_TouchUpInside (UIButton sender)
    {
        StopListening ();
        UpdateButtonStates (false, true, true, true);
    }

    partial void btnSuspend_TouchUpInside (UIButton sender)
    {
        SuspendRecognition ();
        UpdateButtonStates (true, false, true, false);
    }

    partial void btnResume_TouchUpInside (UIButton sender)
    {
        ResumeRecognition ();
        UpdateButtonStates (true, false, false, true);
    }
}

OpenEarsEventsObserverDelegate: OpenEarsEventsObserverDelegate:

// nothing much here just to check the status and debugging 

public class OpenEarsEventsObserverDelegate:OEEventsObserverDelegate
{
    OpenEarsNewApiViewController _controller;

    public OpenEarsNewApiViewController controller {
        get {
            return _controller;
        }
        set {
            _controller = value;
        }
    }

    public OpenEarsEventsObserverDelegate (OpenEarsNewApiViewController ctrl)
    {
        controller = ctrl;
    }

    public override void PocketsphinxRecognitionLoopDidStart()
    {
        //base.PocketsphinxRecognitionLoopDidStart();

        Console.WriteLine ("Pocketsphinx is starting up");
        controller.UpdateStatus ("Pocketsphinx is starting up");
    }

    public override void PocketsphinxDidReceiveHypothesis (Foundation.NSString hypothesis, Foundation.NSString recognitionScore, Foundation.NSString utteranceID)
    {
        controller.UpdateText ("Heard: " + hypothesis);
        controller.Say ("You said: " + hypothesis);
    }

    public override void PocketSphinxContinuousSetupDidFail ()
    {

    }

    public override void PocketsphinxDidCompleteCalibration ()
    {
        Console.WriteLine ("Pocket calibration is complete");
        controller.UpdateStatus ("Pocket calibratio is complete");
    }

    public override void PocketsphinxDidDetectSpeech ()
    {

    }

    public override void PocketsphinxDidStartListening ()
    {
        Console.WriteLine ("Pocketsphinx is now listening");
        controller.UpdateStatus ("Pocketphinx is now listening");
        controller.UpdateButtonStates (true, false, false, true);
    }

    public override void PocketsphinxDidStopListening ()
    {

    }

    public override void PocketsphinxDidStartCalibration ()
    {
        Console.WriteLine ("Pocketsphinx calibration has started.");
        controller.UpdateStatus ("Pocketsphinx calibration has started");
    }

    public override void PocketsphinxDidResumeRecognition ()
    {

    }

    public override void PocketsphinxDidSuspendRecognition ()
    {

    }

    public override void PocketsphinxDidDetectFinishedSpeech ()
    {

    }

    public override void FliteDidStartSpeaking ()
    {

    }

    public override void FliteDidFinishSpeaking ()
    {

    }
}

This works perfectly on iOS simulator but not running on real device. 这在iOS模拟器上完美运行,但不能在真实设备上运行。

模拟器屏幕截图。

I got this Error message while running on device.I'm getting the same message for all the interfaces. 我在设备上运行时收到此错误消息。所有接口都收到相同的消息。

Exception Message :Wrapper type 'OpenEars.OEEventsObserver' is missing its native ObjectiveC class 'OEEventsObserver'.

2015-05-15 12:55:26.996 OpenEarsNewApi[1359:231264] Unhandled managed  exception: Exception has been thrown by the target of an invocation.  (System.Reflection.TargetInvocationException)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj,   System.Object[] parameters) [0x00016] in   /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:543 

Am i missing anything related to Binding for devices? 我是否缺少与绑定设备有关的任何内容?

i tried building the same .dll using make files also, but got the same error message. 我也尝试使用make文件构建相同的.dll,但是得到了相同的错误消息。

For building OpenEars Framework: 对于构建OpenEars框架:

xcodebuild -project OpenEars.xcodeproj -target OpenEars -sdk iphonesimulator8.2 -arch i386 -configuration Release clean build

xcodebuild -project OpenEars.xcodeproj -target OpenEars -sdk iphoneos -arch armv7 -configuration Release clean build

MAKE file for Genrating OpenEars.dll 用于生成OpenEars.dll的文件

BTOUCH=/Developer/MonoTouch/usr/bin/btouch-native

all: OpenEars.dll


OpenEars.dll: AssemblyInfo.cs OpenEars.cs libOpenEars.a
$(BTOUCH) -unsafe --new-style -out:$@ OpenEars.cs -x=AssemblyInfo.cs --link-with=libOpenEars.a,libOpenEars.a

clean:
   -rm -f *.dll

Check the complete mtouch error log here 此处检查完整的mtouch 错误日志

$lipo -info libOpenEars.a

Architectures in the fat file: libOpenEars.a are: i386 armv7 

Check the $nm -arch armv7 libOpenEars.a 检查$ nm -arch armv7 libOpenEars.a

nm command output here nm命令输出在这里

checked the OEEvent exist in simulator (i386) 检查模拟器中是否存在OEEvent(i386)

$ nm -arch i386 libOpenEars.a | grep OEEvent

OUTPUT 输出值

U _OBJC_CLASS_$_OEEventsObserver
00006aa0 S l_OBJC_LABEL_PROTOCOL_$_OEEventsObserverDelegate
000076f0 S l_OBJC_PROTOCOL_$_OEEventsObserverDelegate
warning: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm: no name list
libOpenEars.a(OEEventsObserver.o):
00002174 S _OBJC_CLASS_$_OEEventsObserver
00002170 S _OBJC_IVAR_$_OEEventsObserver._delegate
00002188 S _OBJC_METACLASS_$_OEEventsObserver
     U _OBJC_CLASS_$_OEEventsObserver
00002d90 S l_OBJC_LABEL_PROTOCOL_$_OEEventsObserverDelegate
000035a0 S l_OBJC_PROTOCOL_$_OEEventsObserverDelegate

checked the OEEvent exist in armv7 检查armEvent7中是否存在OEEvent

$nm -arch armv7 libOpenEars.a | grep OEEvent

OUTPUT 输出值

 U _OBJC_CLASS_$_OEEventsObserver
00005680 S l_OBJC_LABEL_PROTOCOL_$_OEEventsObserverDelegate
000062d8 S l_OBJC_PROTOCOL_$_OEEventsObserverDelegate
warning:    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm: no name list
libOpenEars.a(OEEventsObserver.o):
00001cb4 S _OBJC_CLASS_$_OEEventsObserver
00001cb0 S _OBJC_IVAR_$_OEEventsObserver._delegate
00001cc8 S _OBJC_METACLASS_$_OEEventsObserver
     U _OBJC_CLASS_$_OEEventsObserver
00002638 S l_OBJC_LABEL_PROTOCOL_$_OEEventsObserverDelegate
00002e50 S l_OBJC_PROTOCOL_$_OEEventsObserverDelegate

I'm not sure what i am missing. 我不确定我缺少什么。 Yup there is lot of grammar mistakes and i Thank you for your time spend on reading this. 是的,这里有很多语法错误,我感谢您花时间阅读本文。

Thanks @poupou and @Halle for your valuable comments. 感谢@poupou和@Halle的宝贵意见。 Finally i build the fat binary using all the architectures including arm64 and x86_64 (must). 最后,我使用包括arm64和x86_64(必须)在内的所有架构来构建胖二进制文件。 Used lipo to build all in one package.Now that works like charm !... Also set the project properties-> Advanced-> SupportedArchi. 使用lipo将所有内容打包在一个package.Now中,它现在就像魅力!...还要设置项目属性-> Advanced-> SupportedArchi。 -> ARMv7 for running in device like ipad 2 and iPhone 4. Still need to test in iPhone 6 and 6+, i hope that might also support since they are arm64 family. -> ARMv7,可在ipad 2和iPhone 4等设备上运行。仍然需要在iPhone 6和6+中进行测试,我希望它们也可能支持,因为它们是arm64系列。 I'm not sure about how this works on ARMv7s like(iPhone 5, iPhone 5c, iPad 4). 我不确定这在ARMv7(iPhone 5,iPhone 5c,iPad 4)上如何工作。 I'm not seeing the ARMv7s support in OpenEars v2.03. 我在OpenEars v2.03中没有看到ARMv7s支持。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ECGraph不在设备上工作,但在模拟器上工作 - ECGraph not working on device, but works on simulator React 本机应用程序卡在设备的启动屏幕上,但可在模拟器中运行 - React native app stuck on splash screen on device but works in simulator NSUserdefaults在模拟器上有效,但在设备上无效 - NSUserdefaults works on Simulator but not on Device ASIFormDataRequest在模拟器上工作但在设备上不工作? - ASIFormDataRequest works on simulator but not on device? Parse.com Facebook登录屏幕无法在设备上使用,但可以在模拟器上使用 - Parse.com Facebook Sign In Screen not working on device, but works on simulator NSnumberFormatter在模拟器上工作,但不在设备上工作 - NSnumberFormatter working on simulator but not on device Xcode 项目在模拟器中工作,而不是在设备上 - Xcode project works in Simulator, not on device iOS应用程序可在模拟器上运行,但不能在设备上运行 - IOS application works on the simulator but not on the device SQLite插入可在模拟器中使用,但不能在设备上使用 - SQLite insert works in simulator but not on device copyItemAtPath在模拟器上有效,但在设备上失败 - copyItemAtPath works on simulator but fails on device
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM