What is the correct way to define MQL4 "#import of static class methods"? - trading

What I'm trying to achieve is define classes (using MQL4) in separate files and use the methods from those classes in the main code. Essentially importing static class member functions.
class example{ // ____ in example.mq4
public:
static void myfunction(void) export { .. do something .. }
}
class example{ // ____ in example.mqh
public:
static void myfunction(void);
}
#include <example.mqh> // ____ in main.mq4:
#import "example.ex4"
void example::myfunction(void);
#import
Results in a compile error when using the function as follows:
void OnInit(){
example::myfunction();
}
compiler error:
myfunction: function must have a body
(note example.mq4 is compiled to example.ex4 and can be imported ok)

"new"-MQL4 syntax is evolving
for the indicated purpose,
the class definition syntax shall be enough, upon instantiation of a class, its public methods are possible to be invoked on instance-objects.
Compile-time syntax:
Exporting a function without it's class-inheritance ( taking together the whole class container ) does not fit the OOP concept. This is clearly visible in the OnInit() call, where your code attempts to call a function, which is in fact a class-based object-method at a moment, where there has not yet been instantiated any object, on which the method ought to be performed anObjectINSTANCE.aClassOrInstanceMETHOD().
So, just #include
class example{ // ____ in example.mqh
public:
static void myfunction() { .. do something; }
}
// ---------------------------- // ____ in main.mq4
#property strict // "new"-MQL4
#include <example.mqh> // include
example anObject; // create a globally visible instance
// ----------------------------
void OnInit(){
anObject.myfunction(); // request <anObject> to perform <myfunction> method on self
return( EMPTY ); // "new"-MQL4 insists on return even on void fun()
}

Related

Running () on a variable

A little bit confused by the d(); notation...
Is it a kind of semantic shugar? The meaning of d(); should be call() as it described in ReactionDisposer class. I.e. there should be d.call(); will it have the same meaning?
void dispose() {
for (final d in _disposers) { // a list of type ReactionDisposer
d(); // what is it?
}
}
class ReactionDisposer {
ReactionDisposer(this.reaction);
final Reaction reaction;
/// Invoking it will dispose the underlying [reaction]
void call() => reaction.dispose();
}
In Dart, you can use an object as if it is a method/function if the object implements the method call().
So d(); will execute the call() method defined in ReactionDisposer.
You can read about this in the Dart Langauge Tour: https://dart.dev/guides/language/language-tour#callable-classes

Call WebView page method from referenced WinRT Component with AllowForWeb class

I have a XAML page with WebView inside (for example MainPage.xaml). Also I have WinRT Component with class marked with [AllowForWeb] attribute. This component is referenced from project where MainPage.xaml located and in code-behind AddWebAllowedObject method is used. And I can't reference main project back because of circular dependency.
How to call MainPage.xaml.cs methods from component class? Very usual situation. Is there are some standard way to do it?
For example. I have a method inside RT component that could be called from JavaScript
public void ShowMessage(string message)
{
// I want to call here function from MainPage.xaml.cs
}
How to call MainPage.xaml.cs methods from component class? Very usual situation. Is there are some standard way to do it?
Yes, you can pass the method from MainPage.xaml.cs to Windows Runtime Component through delegate(Currently it's very limited to use delegate in Runtime Component using C#, see this case, so I use C++ as demo).
For Runtime Component Class MyClass.h:
public delegate Platform::String^ MyFunc(int a, int b);
public ref class MyClass sealed
{
public:
MyClass();
static Platform::String^ MyMethod(MyFunc^ func)
{
Platform::String^ abc=func(4, 5);
return abc;
}
};
And you can use the delegate in code behind like below:
using MyComponentCpp;
private void myBtn_Click(object sender, RoutedEventArgs e)
{
String abc=MyClass.MyMethod(MyMethod);
myTb.Text = abc;
}
private String MyMethod(int a, int b)
{
return (a.ToString() + b.ToString());//replace this line with your own logic.
}
And here is the complete Demo: TestProject.
Thankfully to #Elvis Xia who has gived me idea, I has found a solution how to do it without C++.
I have create a third project as Class Library. It doesn't has restrictions to use Action. This library I have referenced from main project and from WinRT component. Code of class inside library:
public class BridgeClass
{
public static event Action<string> MessageReceived;
public static void Broadcast(string message)
{
if (MessageReceived != null) MessageReceived(message);
}
}
Code inside main project with webview is:
// place somewhere
BridgeClass.MessageReceived += ShowMessage;
// ....... and add a method
void ShowMessage(string msg)
{
}
And now i can call this code from WinRT component:
public void ShowMessage(string message)
{
BridgeClass.Broadcast("lalala");
}

Reflectable: myAnnotation.annotatedClasses different result CmdApp<>Client

Say I have the following Annotation and 2 classes:
class AppModel extends Reflectable {
final String name;
const AppModel([this.name])
: super(newInstanceCapability, metadataCapability);
}
const appModel = const AppModel();
#appModel
class ImGonnaBePickedUp {
}
#AppModel(' :( ')
class AndImNotPickedUpOnServer_IDoOnWebClient {
}
main() {
appModel.annotatedClasses // that's what I mean by "Picked Up".
}
On CmdApp side (Server): only AndImNotPickedUpOnServer_IDoOnWebClient is given in appModel.annotatedClasses.
On the web side, both classes are given.
Long story short, how do I retrieve classes annotated with direct const constructor calls like in the example above #AppModel(' :( ') (for both CmdApp and Web)?
since version 0.5.4 reflectable classes doesn't support constructors with arguments
This appears in reflectable documentation:
Footnotes: 1. Currently, the only setup which is supported is when the metadata object is an instance of a direct subclass of the class [Reflectable], say MyReflectable, and that subclass defines a const constructor taking zero arguments. This ensures that every subclass of Reflectable used as metadata is a singleton class, which means that the behavior of the instance can be expressed by generating code in the class. Generalizations of this setup may be supported in the future if compelling use cases come up.
one possible solution could be to use a second annotation to handle the name, for example:
import 'package:reflectable/reflectable.dart';
import 'package:drails_commons/drails_commons.dart';
class AppModel extends Reflectable {
const AppModel()
: super(newInstanceCapability, metadataCapability);
}
const appModel = const AppModel();
class TableName {
final String name;
const TableName(this.name);
}
#appModel
class ImGonnaBePickedUp {
}
#appModel
#TableName(' :( ')
class AndImNotPickedUpOnServer_WorksOnWebClient {
}
main() {
print(appModel.annotatedClasses); // that's what I mean by "Picked Up".
print(new GetValueOfAnnotation<TableName>()
.fromDeclaration(appModel.reflectType(AndImNotPickedUpOnServer_WorksOnWebClient)).name);
}
Note: I'm also using drails_common package

using llvm RecursiveASTVisitor for Objective C and iOS

I would like to use clang to preprocess objective C files from an iOS app. I looked over the source code and am trying to implement a pre-processor based on the RecursiveASTVisitor class. However, I seem to be running into many issues that I cannot resolve. I developed a preprocessor to add a "Enter" call at the beginning of each method and an "Exit" call at the end. I also added an "Exit" call before each return statement. I am using the following code to do the instrumentation:
class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
private:
ASTContext *astContext; // used for getting additional AST info
std::string funcName;
public:
explicit ExampleVisitor(CompilerInstance *CI)
: astContext(&(CI->getASTContext())) // initialize private members
{
rewriter.setSourceMgr(astContext->getSourceManager(), astContext->getLangOpts());
}
virtual bool VisitObjCMethodDecl(ObjCMethodDecl *ND) {
funcName = ND->getDeclName().getAsString();
errs() << "Testing function: " << funcName << "\n";
if (ND->hasBody()) {
rewriter.InsertText(ND->getBody()->getSourceRange().getBegin().getLocWithOffset(1), "\nEnter(\""+funcName+"\");\n");
rewriter.InsertText(ND->getBody()->getSourceRange().getEnd(),"Exit(\""+funcName+"\");\n");
}
return true;
}
virtual bool VisitReturnStmt(ReturnStmt *ret) {
rewriter.InsertText(ret->getSourceRange().getBegin(), "\nExit(\""+funcName+"\");\n");
errs() << "** Rewrote ReturnStmt\n";
return true;
}
virtual ~ExampleVisitor() {}
};
class ExampleASTConsumer : public ASTConsumer {
private:
ExampleVisitor *visitor; // doesn't have to be private
public:
// override the constructor in order to pass CI
explicit ExampleASTConsumer(CompilerInstance *CI)
: visitor(new ExampleVisitor(CI)) // initialize the visitor
{ }
// override this to call our ExampleVisitor on the entire source file
virtual void HandleTranslationUnit(ASTContext &Context) {
/* we can use ASTContext to get the TranslationUnitDecl, which is
a single Decl that collectively represents the entire source file */
visitor->TraverseDecl(Context.getTranslationUnitDecl());
}
};
The code compiles. I created a command line executable "instrument". I then used the following command to run this on a simple Objective C program generated by Xcode:
instrument AppDelegate.m --
I run into two problems. First, I get the error: 'UIKit/UIKit.h' file not found. This is one of the includes generated by Xcode. Second, I'm seeing only some of the return statements being processed in the file. Can someone give me some insights into what is happening?
I'm using the 3.7.0 version of llvm.

Do C++ Templates play nicely with VCL classes?

I'm trying to use C++ Template 'mixins' to create some new VCL components with shared additional functionality. Example...
template <class T> class Mixin : public T
{
private:
typedef T inherited;
// ...additional methods
public:
Mixin(TComponent *owner) : inherited(owner)
{
// .. do stuff here
};
};
Used like this:
class MyLabel : public Mixin<TLabel>
{
....
}
class MyEdit : public Mixin<TEdit>
{
....
}
Now, everything compiles fine, and the mixin stuff seems to work - until I try and save the component to a stream using TStream->WriteComponent, where the inherited properties (eg TLabel.Width/Height/etc.) don't get written. This is even with a 'null' mixin like the one shown above.
My code works fine when just deriving classes directly from TForm, TEdit, etc - and the class is correctly registered with the streaming system.
The quick/simple answer is: no; when dealing with a template, the compiler won't generate the proper descriptors to make streaming working. However, since this has come up before, I peeked under the cover to find out what's missing. And what I found is that it's almost there. So here's a little more information.
Upfront the compiler will never treat a template-based type as a Delphi. For example, do something like this:
void testing()
{
__classid(Mixin<Stdctrls::TLabel>); // Error Here
}
... and you'll see the error
"Error E2242 test.cpp 53: __classid requires Delphi style class type (i.e. class marked __declspec(delphiclass) or derived from System::TObject) in function testing()"
This basically says the compiler does not consider this type/class as compatible with Delphi-classes [i.e. those that derive from TObject]. Internally there's just a flag on the symbol that says whether the type is delphi-compatible or not. And I noticed that I could trick the compiler into marking the type as delphi-style if I forced it to walk up the hierarchy.. which is something it has to do if I create an instance of the object. So, with this hack the error goes away:
void testing()
{
typedef Mixin<Stdctrls::TLabel> __ttype;
std::auto_ptr<__ttype> c2(new __ttype(0));
__classid(Mixin<Stdctrls::TLabel>); // No more errors here
}
But much nicer was actually to use the __declspec(delphiclass) directly on the template, as in:
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
So now that the compiler treats the type as a delphi-style class without hacks, I peeked a little more and found the issue you're probably running into: Delphi classes have the TTypeData.PropCount field - http://docwiki.embarcadero.com/VCL/en/TypInfo.TTypeData - which is a sum of the class' properties, including those of its base classes. Due to the way the various pieces of information are computed, the compiler writes out a '0' for that field when a template is involved:(
You can see this by printing out the PropCount, as in:
#include <Stdctrls.hpp>
#include <cstdio>
#include <memory>
#include <utilcls.h>
class TCppComp : public Classes::TComponent {
int i;
public:
__fastcall TCppComp(TComponent* owner): Classes::TComponent(owner) {};
__published:
__property int AAAA = {read=i, write=i};
};
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
typedef Mixin<TCppComp> TMixinComp;
void showProps(TClass meta) {
PTypeInfo pInfo = PTypeInfo(meta->ClassInfo());
int Count = GetPropList(pInfo, tkAny, NULL);
TAPtr<PPropInfo> List(new PPropInfo[Count]);
std::printf("Class: %s - Total Props:%d\n",
AnsiString(pInfo->Name).c_str(), Count);
GetPropList(pInfo, tkAny, *(reinterpret_cast<PPropList*>(&List)));
for (int i = 0; i < Count; i++) {
AnsiString propName(List[i]->Name);
std::printf("\t%s\n", propName.c_str());
}
}
void test() {
showProps(__classid(TCppComp));
showProps(__classid(TMixinComp));
}
int main() {
test();
return 0;
}
When run the above prints:
Class: TCppComp - Total Props:3
AAAA
Name
Tag
Class: #%Mixin$8TCppComp% - Total Props:0
IOW, Mixin shows up with '0' published properties while its base type has 3:(
I suspect the streaming system relies on this count and that's why inherited properties are not being written out in your setup.
I considered tweaking the generated descriptors at runtime but since we write them to _TEXT it's bound to trigger DEP.
I'll look at the logic that computes the PropCount to see if there's some way to get it to compute the correct number. If time allows, please do open a QC for this: now that I've peek underneath, I believe it would not require much effort to get this working as expected.
Cheers,
Bruneau
PS: In my sample I even had the Mixin publish a property and the compiler generated the correct descriptor for that property; however, the total count was still zero.

Resources