Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by beopaul · Dec 22, 2013 at 01:44 AM · iospluginobjective-clinkerarmv7

iOS Objective C plugin linker error

I'm trying to get a simple objective C iOS plugin working and am having problems with linker errors. There's various discussions about this but no clear simple working samples that I can find. See my code below. I'm getting the following error:

Undefined symbols for architecture armv7:

"__getO2", 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) Here's my code. (Note that it's the .h and .m files that don't work. If I replace the .h and .m with the .mm file it runs perfectly): Assets/Scripts/CubeLevitate.cs:
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class CubeLevitate : MonoBehaviour {

[DllImport ("__Internal")]
private static extern float _getO2();

    private float o2Val;

    void Start () {
        o2Val = getO2();
        Debug.Log("Return Float = " + o2Val);
    }
    
    void Update () {
    }
    
    float getO2()
    {
        if (Application.platform == RuntimePlatform.IPhonePlayer)
            return _getO2();
        else
            return 95f;
    }
}
Assets/Plugins/iOS/O2Plugin.h: #import
@interface O2Plugin : NSObject
{ float _getO2; }
@end Assets/Plugins/iOS/O2Plugin.m: #import "O2Plugin.h"
@implementation O2Plugin
-(float)_getO2 { return 98.2f; }
@end Assets/Plugins/iOS/O2Plugin.mm (this works when I replace the .h and .m above with this C++ code, but I want to use Objective C directly. Do I really have to call the obj C from C++?? extern "C" {
float _getO2(void) { return 98.2f; }
bool _initializeBT(void) {
} }
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Statement · Dec 22, 2013 at 01:51 AM 0
Share

I am not a ObjC expert (not even a novice) but check if there is a language feature for exporting types or APIs just like you do with C's extern keyword. Also your ObjC getter appear to exist inside a class (again I am not even a novice so only kick me when I am laying down :-)) so I would guess you'd have to specify which class, which method (and if it is not a static method, which object)

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by beopaul · Dec 22, 2013 at 04:09 PM

Got it working!

  1. Now calling from C++

  2. Changed extension from .m to .mm to accommodate C++ code

  3. Now instantiating the class. Doh!

Here's the fixed code in Assets/Plugins/iOS/O2Plugin.mm:

 #import "O2Plugin.h"
 
 @implementation O2Plugin
 
 static O2Plugin* _O2PluginSingleton = nil;
 
 + (O2Plugin *) O2PluginSingleton
 {
     @synchronized([O2Plugin class])
     {
         if (!_O2PluginSingleton)
         {
             _O2PluginSingleton = [[self alloc] init];
         }
         return _O2PluginSingleton;
     }
     return nil;
 }
 
 -(float) _getO2
 {
     return 98.2f;
 }
 
 @end
 
 extern "C"
 {
     float PGgetO2()
     {
         return [[O2Plugin O2PluginSingleton] _getO2];
     }
     
 
 }
 
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Statement · Dec 22, 2013 at 04:28 PM 0
Share

Glad to hear you found a solution!

I noticed while moderating the posts here on Answers that you sent a couple of duplicate answers to your question. For new users with Low $$anonymous$$arma, all posts are moderated and users with high enough $$anonymous$$arma can approve or reject posts to keep the site clean from bots and the likes. So if you post an answer and don't see it show up instantly, it's because it's awaiting moderation. Accept your own answer to build up a little $$anonymous$$arma and you'll soon be able to post without having to go through moderation :)

avatar image
0

Answer by vladimirg · Dec 22, 2013 at 09:34 AM

Do I really have to call the obj C from C++??

Yes. The documentation is pretty clear on this. (You think that's annoying? Wait until you'll need to pass complex structures to and forth and P/Invoke...)

As for samples, take a look at existing plugins, such as Facebook's.

EDIT: the simple "Yes" given at the beginning is technically wrong (oops). You don't have to use C++ for this, though Objective-C++ is natural for this purpose (as Unity's own files are .mm). You could use Objective C, but as Objective C method calls are actually message passes (which call the C function objc_msgSend behind the scenes), your C/C# interface still has to go through vanilla C functions, which can then use all the nice runtime Objective C facilities. (Technically, since Objective C is a superset of C, you can say that C# is calling Objective C directly! But that's misleading, as only functions can be invoked this way, not methods.)

Still, apart from the use of the extern keyword, this is mostly an academic point, since using C doesn't make your life any user.

And yes, the docs are not too clear, but they're still correct, in their own way.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Statement · Dec 22, 2013 at 04:32 PM 0
Share

Could you please clarify how the doc is clear on this as I had some trouble finding that in the docs you linked to. The docs even state the following:

If you are using C++ (.cpp) or Objective-C++ (.mm) to implement the plugin you must ensure the functions are declared with C linkage to avoid name mangling issues.

Plugins written in C or Objective-C do not need this since these languages do not use name-mangling.

From my best understanding, ObjC should be callable directly from C#, using P/Invoke.

avatar image beopaul · Dec 22, 2013 at 05:21 PM 0
Share

Yup, I read the same text referenced above (regarding plugins written in Objective-C not needing C linkage otherwise needed to prevent name mangling), thus implying that ObjC can be directly linked. I'd love to see a simple example showing this to be the case, though it's largely academic at this point now that I got things working.

avatar image vladimirg · Dec 22, 2013 at 05:42 PM 0
Share

@Statement, you're right, I updated the answer. @beopaul, Objective C can be directly used, just not in a way that gives you the power you need. You still have to write a wrapper, and then it may as well be in Objective C++. Even if you write it in (Objective) C, you have to go through the same motions as with Objective C++.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Call Unity class in XCode 1 Answer

Unity iPhone plugin - what data type to use? 1 Answer

UnitySendMessage and NSString allocation 1 Answer

Linker errors on Xcode 4.5.2 with OpenCV 2.4.3 2 Answers

iOS location permission plugin build fails 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges