How to call multiple C++ functions that are in the same file

Hello everyone,

I am working on a project where I need OpenCV, which is in Cpp. I successfully made the Cpp file, the wrapper, and everything is working fine. However I would now like to display some variables from the Cpp code in the UI. To do so, I made a second function in my Cpp file (which returns the variables I want) and a second wrapper for that function, however I get this error:
Code Block
Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_dataAccessBridge", referenced from:
      objc-class-ref in ViewController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


This is how my code looks like:
  • The cpp file, called imageProcessing.cpp:

Code Block
#include "imageProcessing.hpp"
using namespace cv;
using namespace std;
Mat image_processing::detect_line(Mat image) {
    /*colouring the bright parts of the image in red, just to make sure everything is working*/
    Mat img;
    cvtColor(image, img, CV_RGB2GRAY);
    for(int i = 0; i < image.rows; i) {
        for(int j = 0; j < image.cols; j) {
            if (img.at<uchar>(i, j) > 127) {
                image.at<Vec3b>(i, j)[0] = 255;
                image.at<Vec3b>(i, j)[1] = 0;
                image.at<Vec3b>(i, j)[2] = 0;
            }
        }
    }
    return image;
}
string image_processing::dataAccess() {
    return "hello world from c++";
}
  • The hpp file, called imageProcessing.hpp:

Code Block
#ifndef imageProcessing_hpp
#define imageProcessing_hpp
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <string>
using namespace cv;
using namespace std;
class image_processing {
public:
    Mat detect_line(Mat image);
    string dataAccess();
};
#endif /* imageProcessing_hpp */
  • The .h file of the first wrapper (which is working fine), called imageProcessingBridge.h:

Code Block
#ifndef imageProcessingBridge_h
#define imageProcessingBridge_h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface imageProcessingBridge : NSObject
- (UIImage *) imageProcessingIn: (UIImage *) image;
@end
#endif /* imageProcessingBridge_h */
  • The .mm file of the first wrapper, called imageProcessingBridge.mm:

Code Block
#import <opencv2/opencv.hpp>
#import <opencv2/imgcodecs/ios.h>
#import <Foundation/Foundation.h>
#import "imageProcessingBridge.h"
#import "imageProcessing.hpp"
@implementation imageProcessingBridge
- (UIImage *) imageProcessingIn:(UIImage *)image {
    /* convert UI image to mat */
    cv::Mat opencvImage;
    UIImageToMat(image, opencvImage, true);
    /* convert colorspace */
    cv::Mat convertedColorSpaceImage;
    cv::cvtColor(opencvImage, convertedColorSpaceImage, CV_RGBA2RGB);
    /* Run image processing algorithm */
    image_processing imageProcessing;
    cv::Mat processedImage = imageProcessing.detect_line(convertedColorSpaceImage);
    /* convert mat to UI image and return it to the caller */
    return MatToUIImage(processedImage);
}
@end
  • The .h file of the second wrapper (which is not working), called dataAccessBridge.h:

Code Block
#ifndef dataAccessBridge_h
#define dataAccessBridge_h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface dataAccessBridge : NSObject
- (NSString *) dataAccesOut;
@end
#endif /* dataAccessBridge_h */
  • The .mm file of the second wrapper (which is not working), called dataAccessBridge.mm:

Note that the words NSString, image(underscore)processing, stringWithCString, dataAccess(), c(underscore)str(), encoding:NSUTF8StringEncoding are not coloured, which they become if I copy paste this code in the first wrapper.
Code Block
#import <Foundation/Foundation.h>
#import "dataAccessBridge.h"
#import "imageProcessing.hpp"
@implementation dataAccessBridge
- (NSString *) dataAccessOut {
    image_processing data_access;
    return [NSString
            stringWithCString:data_access.dataAccess().c_str()
            encoding:NSUTF8StringEncoding];
}
@end
  • The ImageProcessingTest-Bridging-Header.h file:

Code Block
#import "imageProcessingBridge.h"
#import "dataAccessBridge.h"
  • How I call the functions in the ViewController.swift file:

Code Block
let processed_image = imageProcessingBridge().imageProcessing(in: image)
self.frameRate.text = dataAccessBridge().imageProcessing()

This last line of code also gives me this error:
Code Block
Value of type 'dataAccessBridge' has no member 'imageProcessing'

But I would assume this is a result of the first error. I also notice that the icons next the dataAccessBridge.h and dataAccessBridge.mm file are greyed out.

What am I doing wrong? Or is it not possible to have 2 wrappers for the same Cpp file? In which case, how should I call the second function?

Thanks in advance
First of all, you use lowercase-leaded names for class names of ObjC, that is making to read your code difficult. Please follow the standard coding rule of ObjC.


In this line of your Swift code, you instantiate the ObjC class dataAccessBridge, and trying to call the instance method of it named imageProcessing.

Code Block
self.frameRate.text = dataAccessBridge().imageProcessing()


But as far as I see your shown code, there are no methods named imageProcessing. What are you trying to do with this line?

Thanks for your reply. I will have a look at the coding rules for Objective C (I do not know that language so I just followed some tutorials).

To what exactly does imageProcessing() in line 1 from my swift code refer to in the first wrapper? If it is line 16 in imageProcessingBridge.mm, I tried changing my swift code to
Code Block
self.frameRate.text = dataAccessBridge().data_access()

but without succes. Note that the first error is now gone (but the second error remains).

If it refers to line 8 (which is strange because it is not the same), the first error remains and the second error is gone.
Code Block
self.frameRate.text = dataAccessBridge().dataAccessOut()


These are probably dumb questions but I could not find any information about how to implement 2 wrappers on the internet, and I do not understand everything yet since I am new to this.

Thanks in advance.

PS. I woud like to edit my question to change my code with the Objective C styling rules, however I don't see the 'edit' button anymore. How shoud I edit my question or is this not possible anymore?



I just followed some tutorials

Seems you should better find a better one.

If it refers to line 8 (which is strange because it is not the same), the first error remains and the second error is gone.

Code Block
self.frameRate.text = dataAccessBridge().dataAccessOut()
I do not see line 8 of what, but as you see dataAccesOut is the only instance method of class dataAccessBridge (declared in dataAccessBridge.h).
You cannot call any other methods, neither imageProcessing nor data_access, through dataAccessBridge()..


Note that the first error is now gone (but the second error remains).

 the first error remains and the second error is gone.

Unfortunately, the build procedure of Xcode sometimes shows odd behaviors, especially when bridging header is included.

Please try Clean(Shift+Cmd+K) + Build(Cmd+B) + re-Build(Cmd+B), keeping the Swift code correct.


How shoud I edit my question or is this not possible anymore?

Unfortunately, this site does not permit us to edit our post after a while (currently 1 hour or so) past from submission. You just can write some replies to show where to fix.

Following the coding rules can be the next thing. Maybe you should better concentrate on building your project successfully.
How to call multiple C&#43;&#43; functions that are in the same file
 
 
Q