• Home
  • Forums
  • Trades
  • News
  • Calendar
  • Market
  • Brokers
  • Login
  • Join
  • User/Email: Password:
  • 6:08am
Menu
  • Forums
  • Trades
  • News
  • Calendar
  • Market
  • Brokers
  • Login
  • Join
  • 6:08am
Sister Sites
  • Metals Mine
  • Energy EXCH
  • Crypto Craft

Options

Bookmark Thread

First Page First Unread Last Page Last Post

Print Thread

Similar Threads

Help: Problem getting File Mapping working with MT4/pascal dll 3 replies

FreePascal DLLs for JMA, EMA, SMA indicators 0 replies

Strategy tester, DLLs, and FreeLibrary() 1 reply

Pascal's Triangle as MM 45 replies

I am having a ball importing DLLs 7 replies

  • Platform Tech
  • /
  • Reply to Thread
  • Subscribe
  • 7
Attachments: Creating Metatrader DLLs with Lazarus / Free Pascal
Exit Attachments
Tags: Creating Metatrader DLLs with Lazarus / Free Pascal
Cancel

Creating Metatrader DLLs with Lazarus / Free Pascal

  • Last Post
  •  
  • Page 1 2345 6
  • Page 1 234 6
  •  
  • Post #1
  • Quote
  • First Post: Edited Dec 15, 2010 3:06am Feb 6, 2010 5:54pm | Edited Dec 15, 2010 3:06am
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
In this thread i will try to collect all the small bits of information that are not so obvious but needed to create DLLs that play together with Metatader, a collection of minimal and self contained code snippets that illustrate how things are done. The intended audience are people already familiar with programming, this is no Pascal tutorial, i will focus only on all the little things that need to be known for Metatrader specific development projects.

I will use Lazarus, the free IDE containing the the Free Pascal compiler FPC, an excellent and very advanced (Object-)Pascal Compiler. I chose Lazarus/FPC because it is by far the easiest and most efficient tool for this job that is available today, and it is free!

Make sure you are downloading the 32 bit version, even if you are running Windows 64 bit on x64 hardware, Metatrader is a 32 bit application and can only use 32 bit DLLs, the 64 bit version of Lazarus/FPC would by default produce 64 bit binaries which can not be used for our purpose.

To create a new DLL project (if you started Lazarus for the first time) click on Project -> new project -> Library. Give it a meaningful name and save it into an empty folder. The project will initially consist of only two files. An .lpi file containing all compiler settings and and .lpr file containing the source code, these two files are all you need to backup, pass on to your colleagues or manage in a source code repository. Additional units (if you decide to split up bigger projects) are saved as individual .pas files.

If you come from a C background you will find it notable that there is no need for make, .def or whatever-files, everything that compiler and linker need to know is written in the pascal source itself, you simply throw the main unit at the compiler and it will figure out everything by itself: http://www.at.freepascal.org/advantage.html

I will expand this first Posting over time with examples of increasing complexity, whenever I have new examples.


1. Minimal example with strings

I will start this thread with a minimal example of a working dll that will show you how to pass strings to your DLL and how to return strings to Metatrader. Since we are using modern Object-Pascal instead of ancient and clumsy C or C++ it is really easy and intuitive:

This is all that is needed on the Pascal side:
Inserted Code
[b]library[/b] minimal;

[color=DeepSkyBlue]{$mode objfpc}{$H+}[/color]

[b]uses[/b]
  sysutils;

[color=SeaGreen]// strings from and to Metatrader will always be passed
// as PChar which is a pointer to a nullterminated C-string.[/color]
[b]function[/b] foo(x: double; y: [color=Blue]PChar[/color]): [color=Blue]PChar[/color]; [b][color=Red]stdcall[/color][/b];
[b]var[/b]
  s :[color=Black]ansistring[/color]; [color=SeaGreen]// reference counted and memory managed strings.[/color]

[b]begin[/b]
[color=SeaGreen]  // our PChar will be copied into an ansistring automatically,
  // no need to worry about the ugly details of memory allocation.[/color]
  s := 'Hello ' + FloatToStr(x) + ' ' + y + '!';

[color=SeaGreen]  // cast it back into a pointer. Metatrader will copy the
  // string from the pointer into it's own memory.[/color]
  result := [color=Blue]PChar[/color](s);
[b]end;[/b]

[b]exports[/b]
  foo;
[b]
begin
end.[/b]
and this is the corresponding mql4:
Inserted Code
#import "minimal.dll"
   [color=SeaGreen]// declare the imported function exactly as it is exported by the dll[/color]
   [color=Blue]string[/color] foo(double x, [color=Blue]string[/color] y);
#import

int init(){
   [color=Blue]string[/color] s = foo(42.3, "Worlds");
   Print(s); [color=SeaGreen]// will print "Hello 42.3 Worlds!"[/color]
}

int start(){
}
The very first and most important thing you need to know about DLLs used for MT4 is marked with red color: Metatrader assumes the 'stdcall' calling convention which means MT4 will push the arguments onto the stack from right to left and our function is responsible for cleaning the stack before returning. FPC's default calling convention would be 'register', also known as 'Borland fastcall', which would use processor registers for the first three 32 Bit arguments. Using the wrong calling convention would immediately crash Metatrader with a segfault due to a messed up stack. Thus we must decorate all exported functions with the keyword stdcall. Another option for achieving the same goal would be the compiler directive {$CALLING STDCALL} at the top of each unit containing exported functions.


2. Passing doubles and integers by reference

By reference means in Metatrader simply putting an ampersand & behind the type identifier in the function declaration and the function can then write values to these arguments. This is a convenient way to return more than one value from a function. Unfortunately with imported functions this seems only possible with arrays. For some weird reason we cannot just pass scalar values by reference to a DLL, MT4 would just push a bunch of zeros onto the stack which is quite useless.

We need to do this with the help of arrays. If we pass an array by reference MT4 will pass a Pointer to the first array element which is easily handled in Pascal either by a typed pointer to an array that can be dereferenced or even more elegantly by declaring the arguments with the keyword var which is technically the same, only nicer:

Inserted Code
[b]library[/b] testlib;

[color=DeepSkyBlue]{$mode objfpc}{$H+}[/color]

[b]type[/b]
  TDPair = array[0..1] of double;
  TIPair = array[0..1] of LongInt;[color=SeaGreen] // 32 bit int[/color]

[color=SeaGreen]// function parameters declared as var will accept pointers.[/color]
[b]procedure[/b] VarsByReference([color=Red][b]var[/b][/color] a: TDPair; [color=Red][b]var[/b][/color] b: TIPair); stdcall;
[b]begin[/b]
  [color=SeaGreen]// now let's make some changes to the variables[/color]
  a[0] += a[1];
  a[1] -= a[0];
  b[0] += b[1];
  b[1] -= b[0];
[b]end;[/b]

[b]exports[/b]
  VarsByReference;

[b]begin[/b]
[b]end.[/b]
and in mql4:

Inserted Code
#import "testlib.dll"
[color=SeaGreen]   /** 
   * the function takes 2 arrays which will be
   * passed by reference. On the DLL side this
   * means we will receive Pointers to the 
   * the memory locations of the arrays 
   */[/color]
   void VarsByReference(double[b][color=Red]&[/color][/b] a[], int[b][color=Red]&[/color][/b] b[]);
#import


int init(){
   double foo[2];[color=SeaGreen] // define pair of doubles[/color]
   int bar[2];    [color=SeaGreen]// define pair of integers[/color]
   
   foo[0] = 1.23;
   foo[1] = 4.56;
   
   bar[0] = 42;
   bar[1] = 23;
   
   VarsByReference(foo, bar);
   
   [color=SeaGreen]// print the changed values[/color]
   Print(foo[0]);
   Print(foo[1]);
   Print(bar[0]);
   Print(bar[1]);
}

int start(){
}


3. Giving the DLL access to all bars in the chart


mql4 has two interesting functions: ArrayCopyRates() and ArrayCopySeries(). These functions, when applied to an empty array, do something interesting with it. Despite the name "copy" they don't actually copy anything, instead they replace the array entirely with something different and very interesting: Once you have applied one of these functions to an array variable, this variable will from now on behave exactly like one of the built-in arrays Time[], Open[], High[], Low[], Close[], Volume[]. It will automatically update when new ticks come in and if you now pass such an array by-reference to your DLL your DLL will receive a pointer to a memory location containing always up to date quotes.

We will use ArrayCopyRates() since this will give us the pointer to a 2-dimensional array, containing time and OHLCV for every bar in the chart.

There is only one noteworthy thing: in mql these series arrays always start with 0 being the current bar, in reality when accessing the memory directly in our DLL, it starts with 0 being the oldest bar and we need to pass an additional parameter to tell the DLL how many bars there are in total so it can figure out which one is the current one. (The array has no upper bound but values beyond the current index (Bars-1) are undefined and meaningless.)

The following example will calculate a simple moving average over the last 14 close prices to illustrate this concept, the mql4 EA will call this function and plot an arrow into the chart at the calculated price:
Inserted Code
[b]library[/b] testlib;

[color=MediumTurquoise]{$mode objfpc}
{$H+}[/color]

[b]type[/b]
  [color=SeaGreen]{ MT4 stores the data of each candle in such a structure.
  MT4 will then give us a pointer to an array of such candles.
  NOTE the unconventional order: open, [b]low, high[/b], close, volume
  instead of OHLCV, this might be wrong in some of the other 
  examples, I noticed it too late, please check your code. 
  This here is the correct definition }[/color]
  TCandle = [b]packed record[/b]
    time:   LongInt; [color=SeaGreen]// POSIX timestamp[/color]
    open,
    low,
    high,
    close,
    volume: double;
  [b]end[/b];

  [color=SeaGreen]{ the following would be a pretty large array but we actually never create
  an instance of it, we only need a typed pointer to such an array.}[/color]
  THistory = [b]array[/b][0..MaxLongInt [b]div[/b] SizeOf(TCandle) - 1] [b]of[/b] TCandle;
  PHistory = ^THistory;

[color=SeaGreen]{ this function demonstrates how use such a PHistory pointer.
Note that unlike in MT4 the array is indexed with 0 being the OLDEST
and history_size - 1 being the CURRENT bar.}[/color]
[b]function[/b] movingAverage(history: PHistory; history_size: LongInt; period: LongInt): Double; stdcall;
[b]var[/b]
  sum: Double;
  i:   LongInt;

[b]begin[/b]
  [b]if[/b] period < 1 [b]then[/b] exit(0);

[color=SeaGreen]   // calculate the average of period last bars' close prices[/color]
  sum := 0;
  [b]for[/b] i := 1 [b]to[/b] period [b]do[/b] [color=SeaGreen]// i=1 is the current bar (history_size - 1)![/color]
  [b]begin[/b]
    sum += history^[history_size - i].close;
  [b]end[/b];
  result := sum / period;
[b]end[/b];

[b]exports[/b]
  movingAverage;

[b]begin[/b]
[b]end[/b].
and in mql4:
Inserted Code
#import "testlib.dll"
   double movingAverage(double& history[][6], int history_size, int period);
#import

double history[][6];

int init(){
[color=SeaGreen]   // This won't actually copy anything, instead it 
   // will make the array point to a metatrader
   // data structure where all candles are stored.
   // You only need to do this once, new candles will
   // be added automatically as time goes by.[/color]
   ArrayCopyRates(history, NULL, 0);
}

int start(){
[color=SeaGreen]   // Bars will always contain the number of usable
   // candles in our array. The DLL needs it to
   // determine the index of the current bar, because
   // in reality (outside of MQL4) this array starts 
   // with 0 being the oldest bar and Bars-1 the current.[/color]
   double ma = movingAverage(history, Bars, 14);
   
[color=SeaGreen]   // draw an arrow at our calculated average price[/color]
   string name = "arrow_" + Time[0];
   ObjectCreate(name, OBJ_ARROW, 0, Time[0], ma);
   ObjectSet(name, OBJPROP_ARROWCODE, 4);
   ObjectSet(name, OBJPROP_PRICE1, ma);
}
This is only an example to demonstrate how to access the bars in the chart. See Post #48 in this thread for a more complete version that properly uses an indicator buffer the way indicators are supposed to be written and indicator buffers are supposed to be used.
  • Post #2
  • Quote
  • Mar 14, 2010 1:59am Mar 14, 2010 1:59am
  •  Time28
  • | Joined Jan 2010 | Status: Member | 26 Posts
Hi 7bit,

many thanks for that.
Is it possible that you give us some more examples ?

Thanks for your help man!

Regards
Time
 
 
  • Post #3
  • Quote
  • Mar 14, 2010 11:42am Mar 14, 2010 11:42am
  •  Cdavid
  • | Joined Apr 2008 | Status: Member | 112 Posts
I agree.
More examples would be great
 
 
  • Post #4
  • Quote
  • Mar 14, 2010 2:15pm Mar 14, 2010 2:15pm
  •  sangmane
  • Joined Apr 2009 | Status: MT4 Programmer | 758 Posts
Wowww, great info!!!
will download lazarus soon. i used to be using delphi, mainly for database application. mql <-> pascal
thank you 7bit
 
 
  • Post #5
  • Quote
  • Edited 4:29pm Mar 24, 2010 2:11pm | Edited 4:29pm
  •  Graff
  • | Joined May 2009 | Status: Member | 35 Posts
Hi there. I'd like to share a small function for correlation calculation in Lazarus. I ported this fuction from mql4(Original code here. Use google to translate it in your languge from russian languge). I ran caculation on multiple TFs and instruments so while calculation my terminal hanged for a few seconds. After rewriting this function on Lazarus calculations are seamless now.

Lazarus code:
PHP Code
 library project1;


{
$mode objfpc}
{
$H+}

type
  
{ MT4 stores the data of each candle in such a structure.
  
MT4 will then give us a pointer to an array of such candles}
  
TCandle = packed record
    time
:   integer; // POSIX timestamp
    
open,
    
high,
    
low,
    
close,
    
volume: double;
  
end;

  { 
the following would be a pretty large array but we actually never create
  an instance of it
, we only need a typed pointer to such an array.}
  
THistory = array[0..MaxInt div SizeOf(TCandle) - 1] of TCandle;
  
PHistory = ^THistory;

{ 
this function demonstrates how use such a PHistory pointer.
Note that unlike in MT4 the array is indexed with 0 being the OLDEST
and history_size - 1 being the CURRENT bar.}
function 
correlation(history_s1: PHistory; history_s2: PHistory; hs1: integer; hs2: integer; n: integer): double; stdcall;
var
  
sx,sy,x,y,cor1,cor2,cor3: double;
  
i:   integer;
begin
  sx
:=0; sy:=0;

  for 
i := 1 to n do // i=1 is the current bar (history_size - 1)!
  
begin
   x
:=0;
   
y:=0;
       
x:=(history_s1^[hs1 - i].open+history_s1^[hs1 - i].close+history_s1^[hs1 - i].high+history_s1^[hs1 - i].low)/4;
       
y:=(history_s2^[hs2 - i].open+history_s2^[hs2 - i].close+history_s2^[hs2 - i].high+history_s2^[hs2 - i].low)/4;
   
sx+=x;sy+=y;
  
end;

  
sx/=n;sy/=n;
  
cor1:=0;cor2:=0;cor3:=0;

  for 
i := 1 to n do // i=1 is the current bar (history_size - 1)!
  
begin
   x
:=0;
   
y:=0;

       
x:=(history_s1^[hs1 - i].open+history_s1^[hs1 - i].close+history_s1^[hs1 - i].high+history_s1^[hs1 - i].low)/4;
       
y:=(history_s2^[hs2 - i].open+history_s2^[hs2 - i].close+history_s2^[hs2 - i].high+history_s2^[hs2 - i].low)/4;

   
cor1+=(x-sx)*(y-sy);
   
cor2+=(x-sx)*(x-sx);
   
cor3+=(y-sy)*(y-sy);
  
end;
  
result := cor1/Sqrt(cor2)/Sqrt(cor3);

end;

exports
  correlation
;

begin
end
. 
MQL4 code:

PHP Code
 #import "project1.dll" double correlation(double& hist_s1[][6],double& hist_s2[][6], int hs1, int hs2, int bn);


double history_s1[][6];
double history_s2[][6];

...

int start()
  {

     
Comment(MTF_MS_Correlation("EURUSD"// Symbol 1
                
,"USDCHF"// Symbol 2
                
,15// Period
                
));

//----
   
return(0);
  }


double MTF_MS_Correlation(string s1, string s2, int tf)
  {
//----
   
int n = 20;
   
int hs1 = ArrayCopyRates(history_s1, s1, tf);
   
int hs2 = ArrayCopyRates(history_s2, s2, tf);
   if(!
hs1 || !hs2 || hs1<=n || hs2<=n){ Print("ArrayCopyRates on " + s2 + " TF " + tf + " failure!"); return(0);}

//----
   
return(correlation(history_s1,history_s2, hs1,hs2,n));       
 } 
7bit thanks a lot.
 
 
  • Post #6
  • Quote
  • Apr 6, 2010 7:26am Apr 6, 2010 7:26am
  •  Relative
  • | Joined Apr 2010 | Status: Junior Member | 6 Posts
Hi 7bit, Programmers !

I'm a beginner Lazarus user. I wanted to try out the first example. So, I installed the Lazarus IDE...

Then
- I created a new Project: 'click on Project -> new project -> Library'.
- Copied the Pascal code to the Source Editor window.
- I saved the project to an empty folder. (I got the two files: .lpi and .lpr)
- I ran the Quick compile. I got other files: .compiled, .exe, .ico, .manifest, .o, .rc. And I got a backup folder too.

But there isn't any DLL file! Where is it?

When I run the Quic compile, I got these error messages too:

Quote
Disliked
minimal(1,1) Warning: Relocatable DLL or executable minimal debug info does not work, disabled.
minimal(1,1) Warning: To allow debugging for win32 code you need to disable relocation with -WN option
Project "minimal" successfully built.
So, what can I do for creating my dll file? How can I disable the mentioned relocation with the -WN option?

Do you have any idea? What can I do? I would be happy, if you could help me.

(I use Windows 7 64bit operating system. But I got the same messages with 32bit Windows XP SP2 too.)

Thank you in advance.

Relative
 
 
  • Post #7
  • Quote
  • Edited 8:42am Apr 6, 2010 8:20am | Edited 8:42am
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting Relative
Disliked
I got other files: .compiled, .exe, .ico, .manifest, .o, .rc. And I got a backup folder too.

But there isn't any DLL file! Where is it?
Ignored
This shouldn't happen. If the first line reads library and not program then it should create a .dll and not an .exe.

I'm currently not at my windows PC where lazarus is installed so i currently can not try out a few ideas i have about what might have gone wrong at your side, but usually it should create a dll without any problems.

Also you shouldn't use quick-compile but build instead. Delete everything except the lpi and the lpr files and then try again.

Which version of lazarus did you donwload? Is it the stable release or one of the snapshots? I personally always use one of the latest snapshots to always have all the newest bleeding edge features but these are not guaranteed to be bug free. I haven't used the official stable release for a long time, so maybe some minor details might be different but the general behaviour must be the same. the first line in a pascal program tells it what type of file it is, program is for .exe, library is for .dll and unit would be a separate module of source code you can later use in other projects and refer to it with the uses clause.
 
 
  • Post #8
  • Quote
  • Edited 9:29am Apr 6, 2010 8:40am | Edited 9:29am
  •  Relative
  • | Joined Apr 2010 | Status: Junior Member | 6 Posts
Quoting 7bit
Disliked
This shouldn't happen. If the first line reads library and not program then it should create a .dll and not an .exe.

I'm currently not at my windows PC where lazarus is installed so i currently can not try out a few ideas i have about what might have gone wrong at your side, but usually it should create a dll without any problems.

Which version of lazarus did you donwload? Is it the stable release or one of the snapshots?
Ignored
Thank you for your fast reply.

I installed Lazarus 0.9.28.2 (lazarus-0.9.28.2-fpc-2.2.4-win64.exe) to my 64bit Windows 7 and the 32bit version (lazarus-0.9.28.2-fpc-2.2.4-win32.exe) to the XP SP2.

About Lasarus info say:

Version #: 0.9.28.2 beta
Date: 2009-10-26
FPC Version: 2.2.4
SVN Revision: 22279
x86_64-win64-win32/win64

Hm! So, this is a beta version? It seems... I looking for a non-beta version...

Anyway, in Lazarus, when I push the F9 (Run), I get this message:

Quote
Disliked
Project "minimal" successfully built.
and a Debug error popup window with this text:

Quote
Disliked
Debug error

Ooops, the debugger entered the error state
Save your work now !

Hit Stop, and hope the best, we're pulling the plug.

[OK]

Quoting 7bit
Disliked
Also you shouldn't use quick-compile but build instead. Delete everything except the lpi and the lpr files and then try again.
Ignored
This works!

You were right! I shouldn't use quick-compile but build instead.

Thank you 7bit for your help and your examples!
 
 
  • Post #9
  • Quote
  • Edited 10:44am Apr 6, 2010 10:32am | Edited 10:44am
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting Relative
Disliked
Hm! So, this is a beta version? It seems... I looking for a non-beta version...
Ignored
It seems the Lazarus core developers suffer from the same symptoms that every perfectionist in software development has if there is no marketing department that steps in and dictates a version number bigger than 1.

The perfectionist's way of version numbering reflects his striving for perfection (which of course can never be reached) and the maturity of the project can be measured by the number of 9's and 8's that appear in the version number while it is asymptotically nearing (but never reaching) the 1.0 mark.

The compiler itself (actually a separate project) is already at 2.x and Lazarus would have deserved the formal 1.0 already 5 years ago. The "beta" or the 0.x doesn't mean anything. Its a only a gigantic understatement by the developers who probably would not even call it 1.0 if some day the bug tracker would be completely empty (which will of course never happen) because they would still have new ideas that are not yet implemented.

The same phenomenon can be observed with projects like mplayer or wine that have been around and are stable and mature for many years now and still carry a version number below 1.

This is the reason why I don't care about the version number anymore, I just use one of the recent builds that proves to be stable enough for me and if I still find a bug in the IDE or the LCL that affects me I try a new snapshot until find one that works for me or try to fix the bug on my own.
 
 
  • Post #10
  • Quote
  • Apr 6, 2010 1:19pm Apr 6, 2010 1:19pm
  •  Relative
  • | Joined Apr 2010 | Status: Junior Member | 6 Posts
Quoting 7bit
Disliked
This is the reason why I don't care about the version number anymore, I just use one of the recent builds that proves to be stable enough for me and if I still find a bug in the IDE or the LCL that affects me I try a new snapshot until find one that works for me or try to fix the bug on my own.
Ignored
I used to use the latest versions too if I can.

___

Now, I have new problem.

So, my minimal.dll file is ready. I copied it the 'MetaTraderexpertslibraries' folder. I made the corresponding MetaTrader script file.

When I executed it in the MetaTrader, I got this error message:

Quote
Disliked
2010.04.06 18:41:42 minimal_script EURUSD,M1: cannot load library 'minimal.dll' (error 126)
It's something like when the dll file miss or it's in a wrong directory.

Do you know why it is this error message?
 
 
  • Post #11
  • Quote
  • Edited 2:59pm Apr 6, 2010 2:39pm | Edited 2:59pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting Relative
Disliked
It's something like when the dll file miss or it's in a wrong directory.
Ignored
126 means it cannot find the dll file. You placed it in the wrong folder or didn't spell its name correctly. It must be in the folder c:/program files/metatrader 4/experts/libraries/ or in c:/program files/metatrader 4/ or in c:/windows/system32 for mt4 to find it.

alternatively you can give the full path name to the dll in the #import directive, for example

#import "c:/foo/bar/somewhere/minimal.dll"

but this is not recommended, this only leads to problems and breaks things if you move folders around.

#import "minimal.dll"

should be sufficient and the dll must be in the experts/libraries/ folder

[the forum here doesn't like backslash, so I use forward slash instead]
 
 
  • Post #12
  • Quote
  • Edited 4:18pm Apr 6, 2010 3:39pm | Edited 4:18pm
  •  Relative
  • | Joined Apr 2010 | Status: Junior Member | 6 Posts
Quoting 7bit
Disliked
126 means it cannot find the dll file. You placed it in the wrong folder or didn't spell its name correctly.
Ignored
Yes, I know. But, it is in the right folder. Other dlls in the same folder work properly.

I just found this topic with similar problem: What can cause 'cannot load library mylib.dll (error 126)'?

...But it couldn't help.

I tried it on Windows XP too. I got the same 'cannot load library' message.
 
 
  • Post #13
  • Quote
  • Apr 6, 2010 4:53pm Apr 6, 2010 4:53pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting Relative
Disliked
I tried it on Windows XP too. I got the same 'cannot load library' message.
Ignored
Sorry, but I have absolutely no idea what you are doing wrong. Error 126 clearly says that it cannot find the dll file, there is no other possible interpretation.

The dll itself has no other dependencies, everything it needs is statically linked, if it can find the dll then it will be able to load it. Maybe you have 2 metatrader installations and accidentially used the wrong one? Maybe you created a link instead of copying the file (this often happens to beginners)? Maybe a problem with file permissions? I have no idea. All my examples were tested and worked before i posted them here. You must be doing something wrong.
 
 
  • Post #14
  • Quote
  • Apr 6, 2010 5:27pm Apr 6, 2010 5:27pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
one thing i forgot:

You may of course not compile it for 64 bit and then use that dll with metatrader which is a 32 bit application (even on windows 64 bit). Maybe you compiled the dll for the 64 bit architecture and used that dll? For metatrader you must use the 32 bit version of lazarus and fpc. (you can cross compile but that may need some additional setup, so better simply install the 32 bit version).

Maybe I should write this into the first posting. I thought this was self-evident.
 
 
  • Post #15
  • Quote
  • Apr 6, 2010 5:54pm Apr 6, 2010 5:54pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Hey, cool. Does this mean you can create a library and share information back and forth between two separate accounts? This is what I downloaded here, and it's supposed to be able to do that. I may check it out here shortly. Except now I'm not sure the hedge option I was trying to setup is going to work, in which case there may not be any point. It would be interesting to see how it works though.
 
 
  • Post #16
  • Quote
  • Apr 6, 2010 6:36pm Apr 6, 2010 6:36pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting ecTrade
Disliked
Hey, cool. Does this mean you can create a library and share information back and forth between two separate accounts?
Ignored
I havent tried this yet with 2 metatraders loading the same dll but theoretically it should work if you place it in the system32 folder where both mt4s can access it.
 
 
  • Post #17
  • Quote
  • Apr 7, 2010 2:25am Apr 7, 2010 2:25am
  •  Relative
  • | Joined Apr 2010 | Status: Junior Member | 6 Posts
Quoting 7bit
Disliked
I havent tried this yet with 2 metatraders loading the same dll but theoretically it should work if you place it in the system32 folder where both mt4s can access it.
Ignored
You can share the folders and the files in it too with Link Shell Extension. For example I have six-seven MetaTrader installed with same 'experts' folder.

Quoting 7bit
Disliked
You may of course not compile it for 64 bit and then use that dll with metatrader which is a 32 bit application (even on windows 64 bit). Maybe you compiled the dll for the 64 bit architecture and used that dll? For metatrader you must use the 32 bit version of lazarus and fpc. (you can cross compile but that may need some additional setup, so better simply install the 32 bit version).
Ignored
This is important information! I never thought I must use the 32 bit version when the 64 bit version exists. I will try it out... Thank you the idea!
 
 
  • Post #18
  • Quote
  • Apr 7, 2010 8:22am Apr 7, 2010 8:22am
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Quoting 7bit
Disliked
I havent tried this yet with 2 metatraders loading the same dll but theoretically it should work if you place it in the system32 folder where both mt4s can access it.
Ignored
Apparently, according to the files I downloaded (the instructions), it should work if you place a copy of the DLL in each of the library folders on each MT4 account.
 
 
  • Post #19
  • Quote
  • Apr 7, 2010 8:59am Apr 7, 2010 8:59am
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting ecTrade
Disliked
Apparently, according to the files I downloaded (the instructions), it should work if you place a copy of the DLL in each of the library folders on each MT4 account.
Ignored
I don't know if windows would regard these two dlls as the *same* dll and load it only once. And even if it did (what i don't believe), what would happen if the two dlls would be slightly different? I don't believe windows would allow such things. If you want both to load the same dll then simply put it into the place that is meant for *shared* libraries: c:/windows/system32/

Maybe the example you are talking about is using entirely different methods for IPC, shared memory for example?
 
 
  • Post #20
  • Quote
  • Apr 7, 2010 11:53am Apr 7, 2010 11:53am
  •  Relative
  • | Joined Apr 2010 | Status: Junior Member | 6 Posts
Quoting 7bit
Disliked
For metatrader you must use the 32 bit version of lazarus and fpc.
Ignored
It works!

Thank you very much 7bit!
 
 
  • Platform Tech
  • /
  • Creating Metatrader DLLs with Lazarus / Free Pascal
  • Reply to Thread
    • Page 1 2345 6
    • Page 1 234 6
0 traders viewing now
  • More
Top of Page
  • Facebook
  • Twitter
About FF
  • Mission
  • Products
  • User Guide
  • Media Kit
  • Blog
  • Contact
FF Products
  • Forums
  • Trades
  • Calendar
  • News
  • Market
  • Brokers
  • Trade Explorer
FF Website
  • Homepage
  • Search
  • Members
  • Report a Bug
Follow FF
  • Facebook
  • Twitter

FF Sister Sites:

  • Metals Mine
  • Energy EXCH
  • Crypto Craft

Forex Factory® is a brand of Fair Economy, Inc.

Terms of Service / ©2023