Day 46/100 100 Days of Code

Chris DourisChris Douris
2 min read

Mixing Objective-C and C++ was quite the adventure. I didn't expect it to be that hard. The problem was that the compiler couldn't locate After a lot of experimentation, I ended up finding the solution on Stack Overflow.

It is not possible to mix C++ and Objective-C like C++ and C. A lot more steps are needed to make it work and these steps will be used to find the game's assets and nothing else.

Objective-C Code

First, I created a macos.h file to create a class that will hold the location of the assets in the .app container.

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

@interface MacBuild : NSObject

    @property (assign) NSBundle *standardBundle;
    @property (assign) NSString *findFontMenuTitle;
    void InitialiseProperties();
@end

Then, I defined the content of the MacBuild object.

# macos.mm
#import "macos.h"

@implementation MacBuild
-    (void) InitialiseProperties{
        self.standardBundle = [NSBundle mainBundle];
        self.findFontMenuTitle = [_standardBundle pathForResource:@"/fonts/ArianVioleta-dz2K" ofType:@"ttf"];
    }
@end

I also made a wrapper .mm file to make the code compatible with c.

# macoswrapper.mm
extern "C"
{
    #import "macos.h"
}

extern "C" MacBuild  *MacBuilder()
{
    MacBuild *macbuild = [[MacBuild alloc] init];
    return macbuild;
}

extern "C" void DestroyMacBuilder(MacBuild *macbuild)
{
    [macbuild dealloc];
}

The code still needs to be tested

Building the Objective-C logic as a separate library

I followed the guide from the stack overflow post to build the library for the Mac build.

# Build MacOs Build file
# Read More: 
# https://stackoverflow.com/questions/76486081/mix-c-and-objective-c-code-using-cmake-and-get-c-executable
add_library(macosbuild MODULE
    ./src/macoswrapper.mm
)

target_sources(macosbuild
  PRIVATE
    ./src/macos.h
    ./src/macos.mm
)

target_link_libraries(macosbuild
    PRIVATE "-framework Cocoa"
    PRIVATE "-framework Foundation"
    PRIVATE "-framework AppKit"
)

# Set the language for the library to Objective-C++
set_target_properties(macosbuild PROPERTIES
    LINKER_LANGUAGE "CXX"
    XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
    XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES YES
    XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES
)

Dynamic linking with the dlfcn library

Instead of including a header file, the guide used the dlfcn library to include the library in the project.

macBuildHandler = dlopen("./builds/lib/libmacosbuild.so", RTLD_LOCAL);

if (!macBuildHandler)
{
    std::cout << "Failed to open mac build library ";
    std::cout << std::strerror(errno) << std::endl;;
    return false; 
}

Like all files, always close the library when we are done.

dlclose(macBuildHandler);

I still need to follow the next steps of the guide to complete the implementation of the Objective-C library and make the application mac compatible.

0
Subscribe to my newsletter

Read articles from Chris Douris directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chris Douris
Chris Douris

AKA Chris, is a software developer from Athens, Greece. He started programming with basic when he was very young. He lost interest in programming during school years but after an unsuccessful career in audio, he decided focus on what he really loves which is technology. He loves working with older languages like C and wants to start programming electronics and microcontrollers because he wants to get into embedded systems programming.