c# - 用于 Unity 的 Objective C iOS 插件

标签 c# ios objective-c xcode unity3d

我在使用我制作的 Objective C 插件在 Xcode 中构建 Unity3d 项目(在设备上进行测试)时遇到问题。
以下是文件:

TestPlugin.h 文件:

#import <Foundation/Foundation.h>

@interface TestPlugin : NSObject

+(int)getGoodNumber;
@end

TestPlugin.m 文件:

#import "TestPlugin.h"

@implementation TestPlugin

+(int)getGoodNumber
{
    return 1111111;
}

@end

最后,统一的 C# 脚本应该打印出 getGoodNumber() 返回的值:

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class PluginTest : MonoBehaviour
{
    [DllImport ("__Internal")]
    public static extern int getGoodNumber();

    void OnGUI()
    {
        string goodNum = getGoodNumber().ToString();
        GUILayout.Label (goodNum);
    }

}

据我所知,代码应该没有任何问题。但是,尽管我遵循了许多不同的教程,但当我尝试编译时,我在 Xcode 中遇到错误:

Undefined symbols for architecture armv7:
  "_getGoodNumber", referenced from:
      RegisterMonoModules() in RegisterMonoModules.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我尝试了一百万种不同的方法,但似乎没有任何帮助。正如我从其他教程中了解到的那样,我不需要对 Xcode 进行任何特殊设置,并且我可以让它们与没有插件的 Unity 项目相同。

我还想澄清一些事情:

  • 插件文件位于Unity3d的/Plugins/iOS/文件夹
  • 构建目标是配备最新 iOS 的 iPad Air 2,因此应该不会出现问题。还在最新的 OS X 版本上使用最新的 Xcode。
  • 我有 Unity3d 的最新可用版本,如果这很重要 - 我有 Unity3d 的专业版。
  • 如果删除插件,该项目将正常运行,因此这不是 Unity3d 和 Xcode 之间的问题。
  • 我认为我不需要在 Objective-C 代码中使用 extern "C" 包装器,因为它是一个“.m”文件,而不是“.mm”,所以不应该有名称修改的问题。
  • 该插件是通过“Cocoa Touch Static Library”模板在 Xcode 中创建的。在将 Xcode 项目导入 Unity3d 之前,我能够自行成功构建 Xcode 项目。

如果有人遇到这样的问题并解决了它,我很想听听解决方案。

最佳答案

您已经编写了“objective-c”类和方法,但不能向 Unity 公开。您需要创建一个“c”方法(然后可以根据需要调用 objective-c 方法)。

例如:

插件.m:

long getGoodNumber() {
  return 111;
}

这是一个更完整的示例,演示了获取陀螺仪的参数。

让我们做一个运动管理器来获取陀螺仪(暂时伪装)。这将是标准的 objective-c:

MyMotionManager.h

@interface MyMotionManager : NSObject { }

+(MyMotionManager*) sharedManager;
-(void) getGyroXYZ:(float[])xyz;

@end

MyMotionManager.m:

@implementation MyMotionManager

+ (MyMotionManager*)sharedManager
{
    static MyMotionManager *sharedManager = nil;
    if( !sharedManager )
        sharedManager = [[MyMotionManager alloc] init];
    return sharedManager;
}

- (void) getGyroXYZ:(float[])xyz
{
    // fake
    xyz[0] = 0.5f;
    xyz[1] = 0.5f;
    xyz[2] = 0.5f;
}

@end

现在让我们通过 C 外部引用公开它(不需要 extern,因为它在 .m(而不是 .mm)中):

MyMotionManagerExterns.m:

#import "MyMotionManager.h"

void GetGyroXYZ(float xyz[])
{
    [[MyMotionManager sharedManager] getGyroXYZ:xyz];
}

最后,在 Unity C# 中调用它:

MotionPlugin.cs:

using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;

public class MotionPlugin 
{
    [DllImport("__Internal")]
    private static extern void GetGyroXYZ(float[] xyz);

    public static Vector3 GetGyro()
    {
        float [] xyz = {0, 0, 0};
            GetGyroXYZ(xyz);
            return new Vector3(xyz[0], xyz[1], xyz[2]);
    }
}

关于c# - 用于 Unity 的 Objective C iOS 插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33276424/

相关文章:

c# - 使用参数和只放置一个变量然后转换它有什么区别

c# - 在我的 Controller 中使用来自其他类库的 View

c# - 来自 NodaTime 中月份和星期几的 LocalDate

ios - 通配符应用程序 ID 不能用于创建内部配置文件。请使用明确的应用程序 ID

objective-c - 如何-editColumn :row:withEvent:select: with NSView-based table view using core data

javascript - 从javascript中的viewbag属性获取值

ios - json.swift 错误是 Self.init 未在委托(delegate)初始化程序的所有路径上调用

iphone - iOS tabBarController 不显示

ios - 为什么将静态引用传递给类会消耗内存?

ios - UITableView 的第一部分被 viewForHeaderInSection 隐藏