Reference a function in EA from library

 

Is there any way I can reference a function in the EA from my custom library, since there are multiple functions that are customer related functions so must be in EA, but are called in specific places in my code in library no matter what the job?

For instance, I have OnTime function, and inside that I have a Calc function. This Calc function is for calculating customer related stuff, so is different for every customer job and needs to be in the EA. I also have another function in OnTimer named DrawPagelayout to draw objects that are customer-job-related, so the DrawPagelayout function needs to be in EA also.

But the library needs to contain references to these since they happen at a specific point in EA.

Is there a way to do this that I have not thought of?

Thanks in advance,

Kindest regards,

Don

Note: When I compile library in library folder right now, I get errors about the functions that are in the EA are missing. But that's beacuse they are in the EA. When I used to use .mqh, I didn't have this problem because even with errors compiling .mqh (I know, you don't compile .mqh but it was habit), the EA would still compile because together between the .mqh and .mq4 EA file, all variables, arrays, and functions existed to give a tradeable .ex4, but I see this is not the case when importing functions and using .ex4.  

 

Try thinking OOP.

Define an interface for callback from a library to EA (mqh-file in Include folder):

class Callback
{
  public:
    virtual void fromLibToCore(double argument) const
    {
      Print("Error: You're calling " + __FUNCTION__ + " which must be overloaded!");
    };
};

Implement you library (mq4-file in Libraries folder) with some exported functions:

#property library
#property strict

#include <bridge.mqh>

const Callback *owner;

void initLibrary(const Callback *c) export
{
  owner = c;
}

void callLibraryOnTick() export
{
  if(CheckPointer(owner) != POINTER_INVALID)
  {
    owner.fromLibToCore(Bid);
  }
}

Note initLibrary function which accepts a Callback object and must be called before any use of the lib.

Finally implement EA which interacts with the lib:

#property strict

#include <bridge.mqh>

#import "bridgedlib.ex4"
  void initLibrary(const Callback *c);
  void callLibraryOnTick();
#import

class ExpertCore
{
  private:
    Callback *c;
  
  public:
    ExpertCore(Callback *v): c(v){}
    virtual ~ExpertCore()
    {
      if(CheckPointer(c) == POINTER_DYNAMIC)
      {
        delete c;
      }
    }
};

class CustomCallback: public Callback
{
  public:
    virtual void fromLibToCore(double argument) const
    {
      Print("Got from lib:", argument);
    }
};

ExpertCore *core;

int OnInit()
{
  CustomCallback *sink = new CustomCallback();
  core = new ExpertCore(sink);
  initLibrary(sink);
  return(0);
}

void OnDeinit(const int reason)
{
  delete core;
}

void OnTick()
{
  callLibraryOnTick();
}

.

 
I'm sorry, it took me a long time to learn MQL4 before they changed it. Can't say I'm familiar with classes. MQL4 was my first programming language and what I still work in, mainly using the old functions before they updated code.
 
Donald R Isbell Jr:
I'm sorry, it took me a long time to learn MQL4 before they changed it. Can't say I'm familiar with classes. MQL4 was my first programming language and what I still work in, mainly using the old functions before they updated code.

That's not so hard to move from functions to classes, but you have other options as well.

You may use EventChartCustom to post data from library and receive it in EA inside OnChartEvent handler, and vice versa.

Also you may introduce a new entity (a helper library file) - a "binding". It should comprise functions to store some data and read stored data. Then you can include this helper module both in your EA and library. From now, they will depend from the helper but neither of them will depend on each other. When library needs to pass something into EA, it should call helper's "store" function, and EA should request the helper periodically or at some events (such as OnTick) if new data is available for reading, then read it and clear the storage. The storage can be either "scalar" (a single item can be held) or a queue (vector with multiple items). This is up to you.

 
Stanislav Korotky:

That's not so hard to move from functions to classes, but you have other options as well.

You may use EventChartCustom to post data from library and receive it in EA inside OnChartEvent handler, and vice versa.

Also you may introduce a new entity (a helper library file) - a "binding". It should comprise functions to store some data and read stored data. Then you can include this helper module both in your EA and library. From now, they will depend from the helper but neither of them will depend on each other. When library needs to pass something into EA, it should call helper's "store" function, and EA should request the helper periodically or at some events (such as OnTick) if new data is available for reading, then read it and clear the storage. The storage can be either "scalar" (a single item can be held) or a queue (vector with multiple items). This is up to you.

Thank you Stanislav :) I will look into the options you have provided.
 
Donald R Isbell Jr:

Is there any way I can reference a function in the EA from my custom library, since there are multiple functions that are customer related functions so must be in EA, but are called in specific places in my code in library no matter what the job?

For instance, I have OnTime function, and inside that I have a Calc function. This Calc function is for calculating customer related stuff, so is different for every customer job and needs to be in the EA. I also have another function in OnTimer named DrawPagelayout to draw objects that are customer-job-related, so the DrawPagelayout function needs to be in EA also.

But the library needs to contain references to these since they happen at a specific point in EA.

Is there a way to do this that I have not thought of?

Thanks in advance,

Kindest regards,

Don

Note: When I compile library in library folder right now, I get errors about the functions that are in the EA are missing. But that's beacuse they are in the EA. When I used to use .mqh, I didn't have this problem because even with errors compiling .mqh (I know, you don't compile .mqh but it was habit), the EA would still compile because together between the .mqh and .mq4 EA file, all variables, arrays, and functions existed to give a tradeable .ex4, but I see this is not the case when importing functions and using .ex4.  

Just use #import
 

I have function in EA that I need to have that data seen and used by library. Many variables and drawn objects in this function in EA.

 Problem is, must have a function in library, so I call it CustomerWorksArea of type void. It is empty with no data. I list function from library in include. But I don't need to make a call to function listed in include when in EA. I need to SEND data to library from EA. So not normal library > EA, but instead EA > library. 

Thanks for trying to help me with this. I am reading and trying to understand new stuff but am having hard time.

Kindest regards,

Don

In library:

void DonsOnTimer() export

  {

 CustomerWorkArea(TradeOnClosedBar);

 };

 void OnTimer()

  {

   DonsOnTimer();

  }

At bottom in library outisde of any other function (I had to declare this function because it is used in library and library would not compile without it):

void CustomerWorkArea(int bar) 

   {

   //Alert("In EMPTY CustomerWorkArea function");

 

In include:

#import "DonsFunctionsLibrary.ex4"

   void OnTimer();

   void DonsOnTimer();

   CustomerWorkArea(int bar); // empty placeholder function. Real function with data in EA.

#import 

 

in EA:

#include <DonsFunctionsInclude.mqh>

void CustomerWorkArea(int bar) {

   Global variables that are changed here, and drawn objects I need seen by library are here. 

}

void OnTimer()

  {

   DonsOnTimer();

  }

 I have no problem getting stuff from DonOnTimer into EA. But DonOnTimer uses function in EA and needs that data (global variables and arrays changing an objects drawn) but it seems that CustomerWorkArea function in EA is not being run, but instead empty one in library same name is being run. 

 

Nevermind, I think it's the way I was thinking of it was all wrong.

I need to instead make a library out of Customer's stuff with CustomerInit, Customer Deinit, and CustomerOnTimer. export those out of librar and import them into include file CustomerInculde. Then include CustomerInclude in EA along with including DonsLibrary, using the 6 exported functions in the EA.

One question though:

I have user inputs and gobal variables and arrays that I must have in each library to compile, but finding I must copy all of those to the include file for the EA to see when included in EA. Why doesn't the EA see the library's declarations of all those variables?

Thanks!

Kindest regards,

Don 

 

I see, just export those 1-3 needed functions from Customer library and import into DonFunctionsLibrary so I can use CustomerWorkArea function in DonsFunctionsLibrary, then export the 3 needed functions from DonsLibrary and import into new EA, which should also take care of the user input, global variables and global arrays problem I was mentioning. Plus has the positive outcome of my library being hidden and protected from change. I just provide my library .ex44, customer library .ex4, and EA .mq4. And no need for include files except for use as a guide to what functions are in library if there are many, as in my case.

Thanks!

Kindest regards,

Don 

 
Donald R Isbell Jr:

I see, just export those 1-3 needed functions from Customer library and import into DonFunctionsLibrary so I can use CustomerWorkArea function in DonsFunctionsLibrary, then export the 3 needed functions from DonsLibrary and import into new EA, which should also take care of the user input, global variables and global arrays problem I was mentioning. Plus has the positive outcome of my library being hidden and protected from change. I just provide my library .ex44, customer library .ex4, and EA .mq4. And no need for include files except for use as a guide to what functions are in library if there are many, as in my case.

Thanks!

Kindest regards,

Don 

OK, this is what I ended up with:

CustomerToDonBridgeLibrary export two bridge functions (CustomerWorkAreaBridge and CustomerObjectsBridge), and imported these two bridge functions into DonLFunctionsLibrary. DonLFunctionsLibrary compiled fine since these two functions (although functions were empty) and their library were there. Now I can send just the ex4 of my library to m customers if they request.

Now after that, the CustomerToDonBridgeLibrary can change, and for each customer job, I import the specific two bridge functions (ActualCustomerNameWorkArea and ActualCustomerNameObjects) into their bridge functions and re-compile CustomerToDonBridgeLibrary.

I import the un-changing named file CustomerToDonBridgeLibrary and it's un-changing named functions CustomerWorkAreaBridge and CustomerObjectsBridge into the EA but don't use them. I import 3 custom functions from DonLFunctionsLibrary (DonInit, DonDeinit, and DonOnTimer) where all work is done, and use them in EAs OnInit, OnDeinit, and InTimer functions, and save and compile EA.

This way, DonLibrary compiles on its own, and I keep the mq4, and give the ex4. I give a library where it's name and functions do not change name, but can change contents per customer job. And I give a customer library that is custom per job. This way, if I am unavailable, the customer can if they choose, go get a change done somewhere else, an only be able to make changes to their strategy or signals but not be able to change my EA shell or how it trades, or be able to copy my code and give it to other developers.

It's working for me. Do you have any advice?

Note: Although this is not built as an object per se, it is working as one. The reason I say this is because the contents of the bridge functions are empty when I compiled my library. So my library ex4's bridge function's contents are empty in ex4 (if the contents were saved with my library ex4, but they're not, just the functions and bridge library are referenced in compiled ex4). When later imported into the EA so the EA can have access to the bridge library, then the most recent bridge library which is no longer empty but whose functions contain the customer's library functions is used.

Thanks.

Kindest regards,

Don 

 

Seems interesting but honestly I don't understand Anyone else ?

Can you provide some demo code ?

Reason: