0

I'm making an app in React-native that uses Djinni from dropbox to bridge between C++ and Javascript. Calling from Javascript to C++ works well but now I'm implementing Call from C++ to Java/ObjC, my C++ skills are so and so. So I'm stuck on initialising class method. I'm basing this on the example provided with Djinni. AnotherClassMain is the access point from Javascript to C++.

I want to call runAProcess method from processAImpl inside anotherClassMain.

But I get the error Field type 'aEditing::ProcessAImpl' is an abstract class On the line ProcesAImpl processA; in anotherClassMain.hpp

How can I access this initiate the class processAImpl and call the runAProcess from anotherClassMain ??

// processA.hpp created by djinni

#pragma once
#include <string>

namespace aEditing {
class ProcessA {
public:
    virtual ~ProcessA() {}
    virtual bool runThisProcess(const std::string & str) = 0;
};
} 

//processAImpl.hpp

#pragma once
#include "processA.hpp"

namespace aEditing {
class ProcessAImpl : public ProcessA {

public:
    ProcessAImpl(const std::shared_ptr<ProcessA> & listener);
    void runAProcess(const std::string aCommand);

private:
    std::shared_ptr<ProcessA> aProcess;
};
}

//processAImpl.cpp

#include "procesAImpl.hpp"
namespace aEditing {

ProcessAImpl::ProcessAImpl (const std::shared_ptr<ProcessA> & listener) {
    this->aProcess = listener;
}

void ProcessAImpl::runAProcess(const std::string aCommand) {
    this->aProcess->runThisProcess(aCommand);
}
}

//anotherClassMain.hpp

#pragma once
#include "includes.hpp"
#include "processAImpl.hpp"

namespace anotherProcessing {

  class AnotherProcessingMain: public anotherProcessing::AnotherProcessing {
    public:
      AnotherProcessingMain();
      string anotherProcessing(const std::string &Input, const std::string &output) override;
    private:
        ProcesAImpl  processA;
  };
}

//anotherClassMain.cpp

#include "anotherClassMain.hpp"

namespace anotherProcessing {
  shared_ptr<AnotherProcessing> AnotherProcessing::create() {
    return make_shared<AnotherProcessingMain>();
  }

  AnotherProcessingMain::AnotherProcessingMain() {}

  string AnotherProcessingMain::anotherProcessing(const std::string &Input, const std::string &output){

    processA.runAProcess("testCommand");  //Trying to access this!

    return "yeah";
  }

2 Answers2

0

How can I access this initiate the class processAImpl and call the runAProcess from anotherClassMain ??

I suppose you mean to instantiate the class processAImpl.
ProcessA is an abstract class because it contains a pure virtual function.
When you derive from an abstract class, you must implement that pure virtual function in the derived class. Otherwise you will not be able to instantiate the derived class.

So implement (provide a definition of) runThisProcess(const std::string & str) in the derived class processAImpl.

P.W
  • 26,289
  • 6
  • 39
  • 76
  • Yes mean to say instantiate :) When I put under processAImpl.hpp public: virtual bool runThisProcess(const std::string & str);' I still get the Error Field type is an abstract class. If I set in anotherClassMain.hpp aEditing::ProcessAImpl processA; instead of ProcessAImpl processA; I get Constructor for 'anotherProcessing::AnotherProcessingMain' must explicitly initialize the member 'processA' which does not have a default constructor – user3840315 Dec 06 '18 at 11:00
  • @user3840315: You have to provide a definition for it like `runThisProcess(const std::string & str) { //do stuff here }` – P.W Dec 06 '18 at 11:02
  • Thanks for your help, just not sure what I'm doing wrong, so I added as you said in processAImpl.hpp `bool runProcess(const std::string & str);` And in processAImpl.cpp `bool ProcessAImpl::runProcess(const int &str){ } ` I get Unknown type name 'ProcessAImpl'; did you mean 'aEditing::ProcessAImpl'? in my anotherClassMain.hpp – user3840315 Dec 06 '18 at 11:21
  • @user3840315: Yes, specify the name of the namespace as well. – P.W Dec 06 '18 at 11:28
  • Then I get ` Constructor for 'anotherProcessing::AnotherProcessingMain' must explicitly initialize the member 'processA' which does not have a default constructor` – user3840315 Dec 06 '18 at 11:41
0

You are missing a declaration of the base classes pure virtual method bool runThisProcess(const std::string &). Did you mean for void ProcessAImpl::runAProcess(const string) to be the implementation?

The name and argument types must match exactly

  • runThisProcess vs runAProcess
  • const std::string & vs const string

You should mark the methods in the subclass that you intend to be overriding base class methods as override (if there can be grandchildren classes) or final (if there can't), so that the compiler can better inform you of typos like this

You are also missing initialisation of AnotherProcessingMain::processA. You need something like

AnotherProcessingMain::AnotherProcessingMain()
  : processA(/* a const std::shared_ptr<ProcessA> & from somewhere */) 
{}

because the only constructor for ProcessAImpl you defined takes a const std::shared_ptr<ProcessA> &.

It is very suspicious that you have ProcessAImpl have a std::shared_ptr<ProcessA> member. There needs to be some class that actually does stuff in it's runThisProcess member, and it should probably be ProcessAImpl. As it currently stands, ProcessAImpl does nothing. You've basically got turtles all the way down.

Caleth
  • 52,200
  • 2
  • 44
  • 75
  • The arguments accidentally came up wrong when I wrote them here, but are correct in the code I'm running :). – user3840315 Dec 06 '18 at 11:03
  • @user3840315 does the name match? – Caleth Dec 06 '18 at 11:05
  • When I match the name it still doesnt allow me to instantiate the class in anotherClassMain.hpp, I added to processAImpl.hpp under public: `bool runProcess(const std::string & str);` And in processAImpl.cpp `bool ProcessAImpl::runProcess(const std::string & str){ }` And that gives me in anotherClassMain.hpp `Unknown type name 'ProcessAImpl'; did you mean 'aEditing::ProcessAImpl'?` Fix that and then I get `Constructor for 'anotherProcessing::AnotherProcessingMain' must explicitly initialize the member 'processA' which does not have a default constructor` – user3840315 Dec 06 '18 at 11:33
  • @user3840315 either add a method `bool ProcessAImpl::runThisProcess(const std::string &)`, or remove the inheritance of `ProcessA`. You can't construct an object of a type that has a non-overridden pure virtual member – Caleth Dec 06 '18 at 11:41
  • Sry meant to write `bool runThisProcess(const std::string & str); ` not `bool runProcess(const std::string & str);` – user3840315 Dec 06 '18 at 11:51
  • Is it possible you could give me an example of how to call runThisProcess in processA.hpp straight from anotherClassMain.cpp without going through processAImpl. I've tried in anotherClassMain.hpp to do `std::shared_ptr aProcess;` and then in anotherClassMain.cpp I do `aProcess->runThisProcess("testCommand");` but I get a nullPtr. – user3840315 Dec 06 '18 at 14:26
  • @user3840315 You need *some class* that inherits from `ProcessA`, and has what you want in it's `runThisProcess` member. You then need to `std::make_shared(/* args... */)` *somewhere*, and pass it to `AnotherProcessingMain` in `AnotherProcessing::create()` – Caleth Dec 06 '18 at 14:29