How To Call my Qt/C++ Dylib from Objective C?

孤街浪徒 提交于 2019-12-01 01:30:28

You need to use an Objective-C++ class, which is a hybrid of Objective-C and C++.

The greatest challenge using one or more Objective-C++ classes in a largely Objective-C project is avoiding exposing C++ classes to the Objective-C classes. Therefore you need to avoid C++ in the Objective-C++ header file and just include the C++ in the implementation file.

For example:

CppWrapper.h:

#import <Foundation/Foundation.h>

@interface CppWrapper : NSObject
- (BOOL)callCppMethodA:(int)param;
@end

CppWrapper.mm:

#import "CppWrapper.h"
#import "cppclass.h"    // C++

@interface CppWrapper()
{
    cppclass *_cppclass;    // C++
}
@end

@implementation CppWrapper

- (id)init
{
    self = [super init];
    if (self) {
        _cppclass = new cppclass();    // C++
    }
    return self;
}

- (void)dealloc
{
    delete _cppclass;    // C++
}

- (BOOL)callCppMethodA:(int)param
{
    return _cppclass->methodA(param);    // C++
}

@end

Use it like this:

CppWrapper *cppWrapper = [CppWrapper new];
[cppWrapper callCppMethodA:123];
Volomike

Another approach would be to not use Qt/C++, but create C++ classes inside of Objective C and avoid Qt altogether, opting for these includes to make life a whole lot easier in C++:

#include <string>
#include <stdio.h>
#include <sqlite3.h>
#include <Foundation/Foundation.h>

string docs

stdio docs

stdio notes

sqlite3 docs

Apple Foundation Class docs

Also, one can (and actually must) mix a little Objective C in their C++ code in order to make life easier. Here's a sample .mm file, which is the file type that lets you mix C++ and Objective C:

#include <string>
#include <stdio.h>
#include <sqlite3.h>
#include <Foundation/Foundation.h>

class Testlib {

public:

  std::string test(std::string sIn) {
    sIn = sIn.append("-response");
    return sIn; 
  }

  NS_RETURNS_RETAINED NSString *test2(NSString *sIn) {
    // note [[funky Objective C syntax]]
    NSString *sOut = [[NSString alloc] init];
    sOut = [NSString stringWithFormat:@"%@-response", sIn];
    return sOut;
  }

};

In order for me to call this from my main.m file, I had to rename it to main.mm and then do something like:

#import <Cocoa/Cocoa.h>
#import "testlib.mm"

int main(int argc, const char * argv[]) {

  // demo Testlib out to the debug log
  Testlib *o = new Testlib();
  std::string s = "";
  s = o->test("request");
  NSLog(@"Result=%s",s.c_str());
  NSLog(@"Result2=%@",o->test2(@"request"));

  // load our GUI
  return NSApplicationMain(argc, argv);
}

So, for the most part, it gives the ease of use of C++, but makes it powerful with the SQLite3 and Apple Foundation Class stuff to do pretty much what one would have used Qt for (without having to include very large Qt runtime framework libraries). However, for the GUI -- Cocoa is pretty sparse on options (dare I say fascist) compared to Qt, which is why I opt to use Mac native WebKit inside Cocoa, which opens up a vast array of GUI styling. Also, by using Mac native WebKit instead of Qt's embedded WebKit, you can decrease the .app size by about 30MB.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!