I'm having an issue building the Unity3d project in Xcode (to test on a device) with a Objective C plug-in I've made.
Here are the files:
The TestPlugin.h
file:
#import <Foundation/Foundation.h>
@interface TestPlugin : NSObject
+(int)getGoodNumber;
@end
The TestPlugin.m
file:
#import "TestPlugin.h"
@implementation TestPlugin
+(int)getGoodNumber
{
return 1111111;
}
@end
And finally the C# script in unity that's supposed to print out the value that getGoodNumber()
returns:
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);
}
}
As much as I can tell there shouldn't be any problem with the code. But even though I followed many different tutorials, when I try to compile I get an error in 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)
I tried a million different things and nothing seems to help. As much as I could read from other tutorials I do not need any special settings for Xcode and I can leave them same as it was for the Unity project without the plug-in.
I would also like to clarify a few things:
/Plugins/iOS/
folder in Unity3dextern "C"
wrapper in Objective-C code as it's a ".m" file, not ".mm", so there shouldn't be a problem of name-mangling.If someone encountered such a problem as solved it, I would love to hear the solution.
You've written an "objective-c" class and method, but that can not be exposed to Unity. You need to create a "c" method (which could then call an objective-c method if needed).
Eg:
plugin.m:
long getGoodNumber() {
return 111;
}
Here is a fuller example that demonstrates out params to get a gyro.
Let's make a motion manager to get gyro (faked out for now). This would be standard 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
Now lets expose it via a C external reference (no need for extern as it's in a .m (not a .mm):
MyMotionManagerExterns.m:
#import "MyMotionManager.h"
void GetGyroXYZ(float xyz[])
{
[[MyMotionManager sharedManager] getGyroXYZ:xyz];
}
Finally, in Unity C# lets call it:
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]);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With