2

I've got a library written in C, where I need to push a call to a method written in Obj-c. I don't want to modify the original code too much, so I decided to create a "bridge" class to handle the calls between C and ObjC:

DRMBridge.h

#ifndef DRMBridge_h
#define DRMBridge_h

#include "DRMBridgeObjC.h"

void bridge_test();


#endif

DRMBridge.c

#import "DRMBridge.h"


void bridge_test() {

    ctest();

 }

Above is compiled as C

Now here's my objc code:

DRMBridgeObjC.h

#ifndef DRMBridgeObjC_h
#define DRMBridgeObjC_h

#import <Foundation/Foundation.h>

@interface DRMBridgeObjC : NSObject

+(void) test;

@end

void ctest();

#endif

DRMBridgeObjC.m

#import "DRMBridgeObjC.h"

@implementation DRMBridgeObjC : NSObject 

+(void) test  {
    NSLog(@"OH YEAH!");
}
@end


void ctest() {
    [DRMBridgeObjC test];
}

Quite simple.

In the C library I want to call my code from I've added: #include "DRMBridge.h" into the .h file and bridge_test(); in .c file.

Now the best part, when I compile I get:

In file included from /Users/krystian/projects/mdb-reader-lib/reader-Include/ios/MDBReader/Class/DRM/DRMBridge.c:5:
In file included from /Users/krystian/projects/mdb-reader-lib/reader-Include/ios/MDBReader/Class/DRM/DRMBridge.h:8:
In file included from /Users/krystian/projects/mdb-reader-lib/reader-Include/ios/MDBReader/Class/DRM/DRMBridgeObjC.h:12:
In file included from /Applications/Xcode64.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.4.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:
/Applications/Xcode64.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.4.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:400:1: error: expected identifier or '('
@class NSString, Protocol;
^
[...]

I went looking, and found this: ios - Parse Issues in NSObjCRuntime, NSZone, and NSObject

However my pch file looks like this:

#import <Availability.h>

#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#endif

I think the issue I have is that the C compiler tries to compile my ObjC file first, instead of the other way around. I've tried changing the order of files inside Compile Sources to make sure that my .m file is above .c file, but still no go.

Something else I have found which made me lost:

when I follow this answer: https://stackoverflow.com/a/20461780/487605 and change the library itself to .m, and call [DRMBridgeObjC test] code from there - it works.... Compiles fine, no errors given, works fine.

This implies to me, that there's something screwed up with my DRMBridge, but what?

Thanks Krystian

Community
  • 1
  • 1
Krystian
  • 3,193
  • 2
  • 33
  • 71

2 Answers2

1

You've seen the solution already. Use #ifdef __ OBJC__ in your Objective-C header file so that only the plain C bits are compiled when including the file from C

gnasher729
  • 51,477
  • 5
  • 75
  • 98
0

DRMBridge.h

#ifndef DRMBridge_h
#define DRMBridge_h

#include <CoreFoundation/CoreFoundation.h> //or put in .pch

CF_EXPORT void bridge_test();

#endif

DRMBridge.m

#import "DRMBridge.h"
#import "DRMBridgeObjC.h"


void bridge_test() {

    ctest(); //or [DRMBridgeObjC test]; if you like

 }

Thats all. And you can include DRMBridge.h in whatever you like: in .c, in .m, in .cpp.

Cy-4AH
  • 4,370
  • 2
  • 15
  • 22
  • It sounds great, but I get `Unknown type CF_ECTERN` :/ Is there something special I should do? – Krystian Oct 30 '15 at 09:16
  • I'm using XCode 6.4 if that matters. – Krystian Oct 30 '15 at 09:22
  • @Krystian, oh `CF_EXPORT` not `CF_EXTERN`. – Cy-4AH Oct 30 '15 at 09:24
  • thanks, I've changed `CF_EXPORT` into `CF_EXTERN`, however still the same issue. When I add `#import "DRMBridgeObjC.h"` into the `DRMBridge.h` file, the `CF_EXPORT` is accepted, however I'm back to the `NSObjCRuntime.h` errors as described in the question. – Krystian Oct 30 '15 at 09:29
  • 1
    Ok, you will need include `CoreFoundation.h` and don't put `DRBridgeObjC.h` in `DRMBridge.h` – Cy-4AH Oct 30 '15 at 09:34
  • @Krystian, Btw. you can trow `CF_EXPORT` away if you not going include `DRMBridge.h` in .cpp. – Cy-4AH Oct 30 '15 at 09:43