2

I am able to run my C++ code to display the image, but am trying to integrate it with some other C code.

I'm looking for a walkthrough of how to write a C wrapper for my C++ code in OpenCV. I will need to be able to call this C++ method in my C code in future!

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
    if( argc != 2)
    {
     cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
     return -1;
    }

    Mat image;
    image = imread(argv[1], CV_LOAD_IMAGE_COLOR);   // Read the file

    if(! image.data )                              // Check for invalid input
    {
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    }

    namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
    imshow( "Display window", image );                   // Show our image inside it.

    waitKey(0);                                          // Wait for a keystroke in the window
    return 0;
}

Here is a sample OpenCV C++ code I am currently working with first.

1 Answer 1

5

To wrap C++ code so that it's callable by C can be done with a few C++ functions that present themselves as C funcs. As an example, Let's imagine I have a class called MyObj....

// MyObj.h
#pragma once
#include <iostream>

class MyObj
{
  int m_thing = 42;
public: 
  MyObj() = default;
  ~MyObj() = default;

  void printThing() const {
    std::cout << "MyObj: " << m_thing << std::endl;
  }
  int getThing() const {
    return m_thing;
  }
  void setThing(int v) {
    m_thing = v;
  }
};

I need to wrap this in some C functions (declared with C-linkage).

// MyObjWrapper.h
#pragma once

/* 
 * use C name mangling if compiling as C++ code. 
 * When compiling as C, this is ignored. 
 */
#ifdef __cplusplus
extern "C" {
#endif

struct ObjWrapper;

/* return a newly created object */
struct ObjWrapper* createObj();

/* delete an object */
void deleteObj(struct ObjWrapper*);

/* do something on an object */
void printThing(const struct ObjWrapper*);

/* get value from object */
int getThing(const struct ObjWrapper*);

/* set value on object */
void setThing(struct ObjWrapper*, int);

#ifdef __cplusplus
}
#endif

Now in the C++ wrapper file, we can encapsulate all of the C++, leaving only a C interface.

// MyObjWrapper.cpp
#include "MyObj.h"
#include "MyObjWrapper.h"
#include <cassert>

/* use C name mangling */
#ifdef __cplusplus
extern "C" {
#endif

struct ObjWrapper
{
  MyObj obj;
};

/* return a newly created object */
struct ObjWrapper* createObj()
{
  return new ObjWrapper;
}

/* delete an object */
void deleteObj(struct ObjWrapper* wrapper)
{
  assert(wrapper);
  delete wrapper;
}

/* do something on an object */
void printThing(const struct ObjWrapper* wrapper)
{
  assert(wrapper);
  wrapper->obj.printThing();
}

/* get value from object */
int getThing(const struct ObjWrapper* wrapper)
{
  assert(wrapper);
  return wrapper->obj.getThing();
}

/* set value on object */
void setThing(struct ObjWrapper* wrapper, int thing)
{
  assert(wrapper);
  wrapper->obj.setThing(thing);
}

#ifdef __cplusplus
}
#endif
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.