0

I have the following scenario: I have a third party library and a header associated with it, that I'm using in my project. I completed my project and now I'm unit testing my code and I want to use a stub library, created by myself, for the third party library.

The header for the third party library contains structures that looks like this:

typedef struct{
    int (*init)(int * var);
    void (*close)(void);
} AInterface

To create my stub version, I created a .cpp file, in which I include the header, and started to implement it like this:

int AInterface::*init(int* var)
{
    return 0;
}

void AInterface::*close(void)
{}

But when I compile my code I get the following error: "stub.cpp:76:33: error: cannot declare pointer to ‘void’ member
void AInterface::*close(void)"

I have searched the internet but with no success.

My questions are:

  • what I am doing wrong here?
  • is there another way to implement the stub?

I have also tried to implement the stub like this:

int initAInterface(int * var);

int (AInterface::*init)(int * var) = &initAInterface;

int initAInterface(int* var)
{
    return 0;
}

But I get the following error:

error: cannot convert ‘int (*)(int*)’ to ‘int (AInterface::*)(int*)’ in initialization
 int (AInterface::*init)(int* var) = &initAInterface;

Also I have no main in my stub .cpp file.

ascarlat
  • 1
  • 1
  • 1
    Why are you declaring function pointers rather than just functions? You usually hand those static functions – Natio2 Jun 27 '22 at 08:08
  • The function pointers in the original `struct` declaration are not pointers-to-member-functions. They are pointers to static functions. So you can't declare their stub replacements as member functions of a class, unless they are static, and even so they would probably need "C" linkage. – user207421 Jun 27 '22 at 08:13
  • This seems to confuse objects and types. `int (AInterface::*init)(int * var) = ...` appears to intialize **the** `AIntetface::init`. But `AIntetface::init` is not static. Every instance of `AIntertface` has its own `init` member, and they all can have different values. And – MSalters Jun 27 '22 at 11:14

1 Answers1

3

Those are function pointers and expect you to give static functions to them, then pass the struct to the library

//#################################################################
//Library header
typedef struct {
    int (*init)(int* var);
    void (*close)(void);
} AInterface;

//#################################################################
//A CPP file somewhere
//You might need extern "C" if you're mixing C and C++
#include "LibraryHeader.h"

int myInitFuction(int* var)
{
    std::cout << "I wrote the init function for this" << std::endl;
    return 0;
}

void myCloseFunction(void){
    std::cout << "I wrote the close function for this" << std::endl;
}

//Or some other function doesn't need to be main if it's not the entry point
int main()
{
    AInterface myInterface;
    myInterface.init = myInitFuction;
    myInterface.close = myCloseFunction;

    SomeLibraryFuction(&myInterface);
}
Natio2
  • 235
  • 1
  • 9
  • This seems to be a course that is trying to teach C++ by starting with more or less equivalent C code. Unless the OP knows C (which doesn't seem to be the case) it would be simpler to just teach C++. – john Jun 27 '22 at 08:14
  • Yeah, that would be crazy. Great hacks for writing OOP C, but hardly used in C++ – Natio2 Jun 27 '22 at 08:15
  • I have tried to implement the stub like this: int initAInterface(int * var); int (AInterface::*init)(int * var) = &initAInterface; int initAInterface(int* var) { return 0; } But I get the following error: error: cannot convert ‘int (*)(int*)’ to ‘int (AInterface::*)(int*)’ in initialization int (AInterface::*init)(int* var) = &initAInterface; Also, I do not have a main() in my stub .cpp file, so the solutin Justin provided it's not useful. – ascarlat Jun 27 '22 at 08:36
  • Reading your edits, I'm wondering what you are trying to achieve? You need to link an instance of the struct to the static functions like in my example. Does the example not meet your goals? The above code will compile and run using those functions – Natio2 Jun 27 '22 at 08:58
  • @Justin: I'm trying to build a stub library that will replace the original one (I do not have access to the code of the original one) and in this stub library I want those function pointers to point to some functions defined by me. Since it's a library, it will not have a main() function so I can't use your example since it involves a main() in which I declare a AInterface variable. – ascarlat Jun 27 '22 at 09:28
  • @Justin: The structures are defined in a header that I can't change. The only thing I can do is write a .cpp in which to give those function pointers some values. The trouble is I don't know how. – ascarlat Jun 27 '22 at 09:51
  • I'm assuming (maybe incorrectly) the library will let you give it the structs when using some of the functions. So in that code it will assign the pointers, and pass it to the library functions (Exactly like the main function), but SomeLibraryFunction(AInterface& myInterface);. (Note the main function can be in a .cpp file)Outside of that I'd probably have to look at the library to help you, since there is something I am missing. – Natio2 Jun 27 '22 at 10:12
  • @ascarlat Edited the code again to illustrate what I mean. Note if the library sets these pointers internally, they will always replace your functions when calling the library – Natio2 Jun 27 '22 at 10:22