views:

344

answers:

1

I am writing an application that required the development of an engine for handling data, but the engine had to be replaceable by another depending on the customers' need. Since each customer had very different needs, I wanted to make each engine separated from the others so we could only deliver the application with the engines the customer required.

So my VS Solution has the following projects: App, Engine_Base, Engine_A, Engine_B App = the exe Engine_Base = the parent class...compiles to a dll and is added to the references of the App through the projec properties Engine_A and Engine_B are both child classes of Engine_Base and both compile to a dll of their own (Engine_A.dll, Engine_B.dll). They are not added to references of App so that they will not be loaded at runtime since we do not want to ship both to all our customers.

Based on the configuration file of the customer we decide which engine to load:

Engine_Base^  engine_for_app;
Assembly^ SampleAssembly;
Type^  engineType;

if (this->M_ENGINE == "A")
{
 SampleAssembly = Assembly::LoadFrom("path\\Engine_A.dll");

 engineType = SampleAssembly->GetType("Engine_A");
 engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2));
}
else
{
 SampleAssembly = Assembly::LoadFrom("path\\Engine_B.dll");

 engineType = SampleAssembly->GetType("Engine_B");
 engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2, param3, param4));
}

Since only Engine_Base is added to the references of the C++ project we cast our Engine__A or Engine_B objects to the parent type.

Then we set the Events for the threaded execution of our engines as they take a long time to run (lots of data to process):

engine_for_app->OnComplete += gcnew CompleteEngineProcess(this, &frmMain::ThreadChildComplete);
engine_for_app->OnProgressInit += gcnew ProgressInitEngine(this, &frmMain::ThreadChildProgressInit);
engine_for_app->OnProgressReport += gcnew ProgressReportEngine(this, &frmMain::ThreadChildProgressReport);

Thread^ aThread;
aThread = gcnew Thread(gcnew ThreadStart(engine_for_app, &Engine_Base::Read));

But this gives me a:

Error   2 error C3754: delegate constructor: member function 'Engine_A::Read' cannot be called on an instance of type 'Engine_Base ^' d:\_activeWork\EDI_TRUNK\src\App\frmMain.cpp 492

I realize that this has to do with inheritance, but I'm getting short on ideas of how to fix this.

Does anyone have ideas on how to fix this?

Is our approach an alright solution or should we have been looking at something else and done things differently?

A: 

Edit: Maybe make sure Engine_A, etc. methods are marked virtual?

PiNoYBoY82
The engine being used is dynamic, it has to specified as the base class in code.
Got it. You sure the method is marked virtual??
PiNoYBoY82
Marking the functions as virtual didn't have any effect of the behavior. Marking the base class as virtual gives the following error:Error 11 error C2889: 'Engine_Base' : a managed class type cannot be a virtual base class
Dewm Solo