NexusFi: Find Your Edge


Home Menu

 





Calling external DLL from EasyLanguage


Discussion in EasyLanguage Programming

Updated
      Top Posters
    1. looks_one Fu510n with 3 posts (4 thanks)
    2. looks_two rosasurfer with 2 posts (2 thanks)
    3. looks_3 Big Mike with 2 posts (4 thanks)
    4. looks_4 ludvig with 1 posts (0 thanks)
      Best Posters
    1. looks_one Nicolas11 with 4 thanks per post
    2. looks_two Big Mike with 2 thanks per post
    3. looks_3 Fu510n with 1.3 thanks per post
    4. looks_4 rosasurfer with 1 thanks per post
    1. trending_up 25,202 views
    2. thumb_up 15 thanks given
    3. group 9 followers
    1. forum 11 posts
    2. attach_file 0 attachments




 
Search this Thread

Calling external DLL from EasyLanguage

  #1 (permalink)
 
Big Mike's Avatar
 Big Mike 
Manta, Ecuador
Site Administrator
Developer
Swing Trader
 
Experience: Advanced
Platform: Custom solution
Broker: IBKR
Trading: Stocks & Futures
Frequency: Every few days
Duration: Weeks
Posts: 50,460 since Jun 2009
Thanks Given: 33,234
Thanks Received: 101,655


ehlaban View Post
Could somebody point me to some good description/tutorial/explanation on how to call an external DLL from Multicharts or Easylanguage if that's no different.

Ernesto

This example is for Visual Studio C++

Courtesy user wegi from MultiCharts forum:
TS SUPPORT :: View topic - Request : dll example

VS: New - Project - Win32 DLL

 
Code
                            
extern "C" LPCSTR __declspecdllexport __stdcall intToAsc(int v

 
   try{ 
 
      
char buffer [255]; 
      
sprintf (buffer,"%c"v); 
 
      return 
buffer
 
   } 
   catch(...){ 
      
LPCSTR sValue "ERR EXCEPTION"
        return 
sValue
   } 
 

Then create a DEF file to declare the functions exported:

 
Code
                            
EXPORTS    intToAsc 

Then use this EasyLanguage code:

 
Code
                            

vars
tab(""); 
 
DefineDLLFunc"dlltest.dll",  lpstr"intToAsc"int
 
if 
tab "" then tab intToAsc(9); 
Mike

We're here to help: just ask the community or contact our Help Desk

Quick Links: Change your Username or Register as a Vendor
Searching for trading reviews? Review this list
Lifetime Elite Membership: Sign-up for only $149 USD
Exclusive money saving offers from our Site Sponsors: Browse Offers
Report problems with the site: Using the NexusFi changelog thread
Follow me on Twitter Visit my NexusFi Trade Journal Started this thread Reply With Quote
Thanked by:

Can you help answer these questions
from other members on NexusFi?
How to apply profiles
Traders Hideout
MC PL editor upgrade
MultiCharts
NT7 Indicator Script Troubleshooting - Camarilla Pivots
NinjaTrader
Cheap historycal L1 data for stocks
Stocks and ETFs
NexusFi Journal Challenge - May 2024
Feedback and Announcements
 
  #2 (permalink)
 thinkfuture 
Chicago IL
 
Experience: Intermediate
Platform: TradeStation
Broker: RJO Brien
Trading: ES, CL
Posts: 25 since Mar 2010
Thanks Given: 3
Thanks Received: 23

This sounds Great Mike!
Does this mean, the DLL's created for NT can be imported directly into Easy Language & we don't have to convert the indicator or strategy to Easy Language?

If not I wish there was an easy way to do this, please let me know if you have any ideas on easy portability between NT & Easy Language.

Reply With Quote
Thanked by:
  #3 (permalink)
 
Big Mike's Avatar
 Big Mike 
Manta, Ecuador
Site Administrator
Developer
Swing Trader
 
Experience: Advanced
Platform: Custom solution
Broker: IBKR
Trading: Stocks & Futures
Frequency: Every few days
Duration: Weeks
Posts: 50,460 since Jun 2009
Thanks Given: 33,234
Thanks Received: 101,655



thinkfuture View Post
This sounds Great Mike!
Does this mean, the DLL's created for NT can be imported directly into Easy Language & we don't have to convert the indicator or strategy to Easy Language?

If not I wish there was an easy way to do this, please let me know if you have any ideas on easy portability between NT & Easy Language.

No, it's not that simple.

It just means if there is something you want to do that can't be done in EasyLanguage, you could pass variables to/from a DLL and have your C++ do it.

As for NT -> EL conversion, it is case by case. I suggest creating a new thread here in the EasyLanguage Programming section for each indicator you want converted, attach a screen shot or two and the NinjaTrader .cs source, and then someone can probably covert it.

Mike

We're here to help: just ask the community or contact our Help Desk

Quick Links: Change your Username or Register as a Vendor
Searching for trading reviews? Review this list
Lifetime Elite Membership: Sign-up for only $149 USD
Exclusive money saving offers from our Site Sponsors: Browse Offers
Report problems with the site: Using the NexusFi changelog thread
Follow me on Twitter Visit my NexusFi Trade Journal Started this thread Reply With Quote
Thanked by:
  #4 (permalink)
 
Fu510n's Avatar
 Fu510n 
Suffield, CT
 
Experience: Advanced
Platform: MC, TS, Python, Rust
Broker: IB, IQFeed, TS, Kraken
Trading: ES, NQ, RTY, YM, CL, RB, 6E
Frequency: Several times daily
Duration: Seconds
Posts: 144 since Oct 2009
Thanks Given: 902
Thanks Received: 143


Big Mike View Post
This example is for Visual Studio C++

Courtesy user wegi from MultiCharts forum:
TS SUPPORT :: View topic - Request : dll example

VS: New - Project - Win32 DLL

 
Code
                            
extern "C" LPCSTR __declspecdllexport __stdcall intToAsc(int v

 
   try{ 
 
      
char buffer [255]; 
      
sprintf (buffer,"%c"v); 
 
      return 
buffer
 
   } 
   catch(...){ 
      
LPCSTR sValue "ERR EXCEPTION"
        return 
sValue
   } 
 

Then create a DEF file to declare the functions exported:

 
Code
                            
EXPORTS    intToAsc 

Then use this EasyLanguage code:

 
Code
                            


vars
tab(""); 
 
DefineDLLFunc"dlltest.dll",  lpstr"intToAsc"int
 
if 
tab "" then tab intToAsc(9); 
Mike

Sooo...

I'm in the middle of trying to convert the (futures.io (formerly BMT) Elite) "Myst" strategy from NinjaTrader to MultiCharts 7.4 which lead me down a path trying to implement some of the toolbar functionality that NT handles natively in C# as a C/C++ DLL. I may go the C# or even PowerBasic DLL route at some point, but wanted to start with the most direct method first. Given I've yet to try to extend MC via DLLs, this seemed like a worthwhile exercise to see what was involved. I read the TradeStation/EasyLanguage PDF references and several postings on the web that specifically state that function prototypes need to be defined as "__stdcall" rather than "__cdecl" but MC was unable to locate the functions I defined via DefineDLLFunc due to the mangling that occurred by declaring the functions as "__stdcall" (e.g. bad_function( int ) is exposed as _bad_function@4).

I shot MC support an Email and they referred me to GlobalVariable.dll which exposes the functions without "mangling" the function names which makes me wonder if they used the recommended "__stdcall" method as well - requests for access to the GlobalVarialble.dll source haven't been answered .

I wrote a quickee C/C++ test harness using "__cdecl" (on Visual Studio 2010) that others may find helpful. I'd still be interested in hearing if anyone has been able to create and call DLLs by defining functions using "__stdcall" - attempts at going that route lead MC to report "Can't find function "blah" in dll.". These functions do nothing beyond returning the value passed, but it's a start (K.I.S.S.).

-Guy

p.s. BTW, wouldn't your example above return a string pointer from a stack frame that may cause "bad bahavior" - just curious - it's been a while since I've dabbled in C/C++...
 
Code
                            
// MystToolBarWin32.h


#ifdef MYSTTOOLBARWIN32_EXPORTS
#define MYSTTOOLBARWIN32_API __declspec(dllexport)
#else
#define MYSTTOOLBARWIN32_API __declspec(dllimport)
#endif

extern "C" {
    
MYSTTOOLBARWIN32_API int __stdcall bad_functionint v );
    
MYSTTOOLBARWIN32_API int __cdecl good_functionint v );

    
MYSTTOOLBARWIN32_API unsigned char  __cdecl test_byteunsigned char b );
    
MYSTTOOLBARWIN32_API char           __cdecl test_charchar b );
    
MYSTTOOLBARWIN32_API LPSTR          __cdecl test_lpstrLPSTR s );

    
MYSTTOOLBARWIN32_API unsigned short __cdecl test_wordunsigned short w );
    
MYSTTOOLBARWIN32_API unsigned int   __cdecl test_dwordunsigned int dw );
    
MYSTTOOLBARWIN32_API unsigned int   __cdecl test_boolunsigned int b );
    
MYSTTOOLBARWIN32_API int            __cdecl test_intint i );
    
MYSTTOOLBARWIN32_API long           __cdecl test_longlong l );

    
MYSTTOOLBARWIN32_API float         __cdecl test_floatfloat f );
    
MYSTTOOLBARWIN32_API double        __cdecl test_doubledouble d );

 
Code
                            
// MystToolBarWin32.cpp : Defines the exported functions for the DLL application.


#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"

#include "MystToolBarWin32.h"

extern "C" MYSTTOOLBARWIN32_API int __stdcall bad_functionint v )
{
    return 
123;
}

extern "C" MYSTTOOLBARWIN32_API int __cdecl good_functionint v )
{
    return 
456;
}

extern "C" MYSTTOOLBARWIN32_API unsigned char __cdecl test_byteunsigned char b )
{
    return 
b;
}

extern "C" MYSTTOOLBARWIN32_API char __cdecl test_charchar b )
{
    return 
b;
}

extern "C" MYSTTOOLBARWIN32_API LPSTR __cdecl test_lpstrLPSTR s )
{
    return 
s;
}

extern "C" MYSTTOOLBARWIN32_API unsigned short __cdecl test_wordunsigned short w )
{
    return 
w;
}

extern "C" MYSTTOOLBARWIN32_API unsigned int __cdecl test_dwordunsigned int dw )
{
    return 
dw;
}

extern "C" MYSTTOOLBARWIN32_API unsigned int __cdecl test_boolunsigned int b )
{
    return 
b;
}

extern "C" MYSTTOOLBARWIN32_API int __cdecl test_intint i )
{
    return 
i;
}

extern "C" MYSTTOOLBARWIN32_API long __cdecl test_longlong l )
{
    return 
l;
}

extern "C" MYSTTOOLBARWIN32_API float __cdecl test_floatfloat f )
{
    return 
f;
}

extern "C" MYSTTOOLBARWIN32_API double __cdecl test_doubledouble d )
{
    return 
d;

 
Code
                            
// Fu510nDLLTest - MultiCharts DLL test harness (writes output to Output window)


vars:
    
int idx),
    
int n),
    
float f0.0 ),
    
double d10.0 ),
    
s1"string" ),
    
s2"" );

array:
    
nArray[9]( );

DefineDLLFunc"MystToolBarWin32.dll"byte,   "test_byte",   byte;   // 1 byte integer
DefineDLLFunc"MystToolBarWin32.dll"char,   "test_char",   char;   // 1 byte integer
DefineDLLFunc"MystToolBarWin32.dll"word,   "test_word",   word;   // 2 byte unsigned integer
DefineDLLFunc"MystToolBarWin32.dll"dword,  "test_dword",  dword;  // 4 byte unsigned integer
DefineDLLFunc"MystToolBarWin32.dll"bool,   "test_bool",   bool;   // 4 byte boolean
DefineDLLFunc"MystToolBarWin32.dll"int,    "test_int",    int;    // 4 byte signed integer
DefineDLLFunc"MystToolBarWin32.dll"long,   "test_long",   long;   // 4 byte signed integer
DefineDLLFunc"MystToolBarWin32.dll"float,  "test_float",  float;  // 4 byte floating point
DefineDLLFunc"MystToolBarWin32.dll"double"test_double"double// 8 byte floating point
DefineDLLFunc"MystToolBarWin32.dll"LPSTR,  "test_lpstr",  LPSTR;  // pointer to a char

once begin

    nArray
[0] = 0;
    
nArray[1] = 127;
    
nArray[2] = 128;
    
nArray[3] = 255;
    
nArray[4] = -1;
    
nArray[5] = 256;
    
nArray[6] = 65536;
    
nArray[7] = 65536*256;
    
nArray[8] = 65536*65536;

    
ClearDebug();

    for 
idx 0 to 5 begin
        n 
test_bytenArray[idx] );
        
MessageLog"test_byte( "nArray[idx]:0:0" )=[ "n:0:0" ]" );
    
end;

    
MessageLog"" );

    for 
idx 0 to 5 begin
        n 
test_charnArray[idx] );
        
MessageLog"test_char( "nArray[idx]:0:0" )=[ "n:0:0" ]" );
    
end;

    
MessageLog"" );

    
s2 test_lpstrs1 );
    
MessageLog"test_lpstr( "s1" )=[ "s2 " ]" );

    
MessageLog"" );

    for 
idx 0 to 6 begin
        n 
test_wordnArray[idx] );
        
MessageLog"test_word( "nArray[idx]:0:0" )=[ "n:0:0" ]" );
    
end;

    
MessageLog"" );

    for 
idx 0 to 8 begin
        n 
test_dwordnArray[idx] );
        
MessageLog"test_dword( "nArray[idx]:0:0" )=[ "n:0:0" ]" );
    
end;

    
MessageLog"" );

    
MessageLog"test_bool( False )=[ "test_boolFalse ), " ]" );
    
MessageLog"test_bool( True )=[ "test_boolTrue ), " ]" );

    
MessageLog"" );

    
nArray[8] = 65536*32768-1;
    
nArray[9] = -(65536*32768);

    for 
idx 0 to 9 begin
        n 
test_intnArray[idx] );
        
MessageLog"test_int( "nArray[idx]:0:0" )=[ "n:0:0" ]" );
    
end;

    
MessageLog"" );

    for 
idx 0 to 9 begin
        n 
test_longnArray[idx] );
        
MessageLog"test_long( "nArray[idx]:0:0" )=[ "n:0:0" ]" );
    
end;

    
MessageLog"" );

    
test_float123456.123456 );
    
MessageLog"test_float( "123456.123456:8:8" )=[ "f:8:8" ]" );

    
MessageLog"" );

    
d1 test_double12345678.12345678 );
    
MessageLog"test_double( "12345678.12345678:8:8" )=[ "d1:8:8" ]" );

end
 
Code
                            
test_byte)=[ ]

test_byte127 )=[ 127 ]
test_byte128 )=[ 128 ]
test_byte255 )=[ 255 ]
test_byte( -)=[ 255 ]
test_byte256 )=[ ]

test_char)=[ ]
test_char127 )=[ 127 ]
test_char128 )=[ -128 ]
test_char255 )=[ -]
test_char( -)=[ -]
test_char256 )=[ ]

test_lpstr( string )=[ string ]

test_word)=[ ]
test_word127 )=[ 127 ]
test_word128 )=[ 128 ]
test_word255 )=[ 255 ]
test_word( -)=[ 65535 ]
test_word256 )=[ 256 ]
test_word65536 )=[ ]

test_dword)=[ ]
test_dword127 )=[ 127 ]
test_dword128 )=[ 128 ]
test_dword255 )=[ 255 ]
test_dword( -)=[ 4294967295 ]
test_dword256 )=[ 256 ]
test_dword65536 )=[ 65536 ]
test_dword16777216 )=[ 16777216 ]
test_dword4294967296 )=[ ]

test_boolFalse )=[ FALSE ]
test_boolTrue )=[ TRUE ]

test_int)=[ ]
test_int127 )=[ 127 ]
test_int128 )=[ 128 ]
test_int255 )=[ 255 ]
test_int( -)=[ -]
test_int256 )=[ 256 ]
test_int65536 )=[ 65536 ]
test_int16777216 )=[ 16777216 ]
test_int2147483647 )=[ 2147483647 ]
test_int( -2147483648 )=[ -2147483648 ]

test_long)=[ ]
test_long127 )=[ 127 ]
test_long128 )=[ 128 ]
test_long255 )=[ 255 ]
test_long( -)=[ -]
test_long256 )=[ 256 ]
test_long65536 )=[ 65536 ]
test_long16777216 )=[ 16777216 ]
test_long2147483647 )=[ 2147483647 ]
test_long( -2147483648 )=[ -2147483648 ]

test_float123456.12345600 )=[ 123456.12500000 ]

test_double12345678.12345678 )=[ 12345678.12345678 

Follow me on Twitter Reply With Quote
Thanked by:
  #5 (permalink)
ludvig
russia kaliningrad
 
Posts: 19 since Jan 2011
Thanks Given: 0
Thanks Received: 21

Thank you Fu510n for posting this code, but I have a trouble to realize it. I copy your text into VC2010(express edition), compile, put the dll to TSSupport\Multicharts folder and after I open PL indicator on chart, i have this message:

<<EXCEPTION>>
Address: 0x65641407 ( 1701057543 )
Code: 0xC0000005 ( -1073741819 )
Continuable: 0x00000000 ( 0 )
Description: Instraction for adress "0x
ErrorCode: 0xC0000005 ( -1073741819 )
ExceptionType: 0x00000000 ( 0 )
Module: C:\Documents and Settings\All Users\Application Data\TS Support\MultiCharts\StudyServer\Studies\Dlls\Indicators\i_my_indicator.dll
Process: C:\Program Files\TS Support\MultiCharts\MultiCharts.exe
Thread ID: 0x000013F4 ( 5108 )
Time: 27.05.2012 - 01:36:02.768

Whot do you think may be the reason, can you help me?

Reply With Quote
  #6 (permalink)
 
Nicolas11's Avatar
 Nicolas11 
near Paris, France
 
Experience: Beginner
Platform: -
Trading: -
Posts: 1,071 since Aug 2011
Thanks Given: 2,232
Thanks Received: 1,769

Some references that I have not tested myself...

Step by step guide for developing a C++ DLL (Dynamic Link Library) that can be used with MultiCharts’ PowerLanguage: Extending [AUTOLINK]MultiCharts[/AUTOLINK] Capabilities with C++ | Aurora Solutions

This thread on MultiCharts forum: MultiCharts: Trading Software for Automated Trading and [AUTOLINK]Backtesting[/AUTOLINK] ? View topic - [Advanced Topic] Programming DLL

Nicolas

Visit my NexusFi Trade Journal Reply With Quote
  #7 (permalink)
 
Fu510n's Avatar
 Fu510n 
Suffield, CT
 
Experience: Advanced
Platform: MC, TS, Python, Rust
Broker: IB, IQFeed, TS, Kraken
Trading: ES, NQ, RTY, YM, CL, RB, 6E
Frequency: Several times daily
Duration: Seconds
Posts: 144 since Oct 2009
Thanks Given: 902
Thanks Received: 143


ludvig View Post
Thank you Fu510n for posting this code, but I have a trouble to realize it. I copy your text into VC2010(express edition), compile, put the dll to TSSupport\Multicharts folder and after I open PL indicator on chart, i have this message:

<<EXCEPTION>>
Address: 0x65641407 ( 1701057543 )
Code: 0xC0000005 ( -1073741819 )
Continuable: 0x00000000 ( 0 )
Description: Instraction for adress "0x
ErrorCode: 0xC0000005 ( -1073741819 )
ExceptionType: 0x00000000 ( 0 )
Module: C:\Documents and Settings\All Users\Application Data\TS Support\MultiCharts\StudyServer\Studies\Dlls\Indicators\i_my_indicator.dll
Process: C:\Program Files\TS Support\MultiCharts\MultiCharts.exe
Thread ID: 0x000013F4 ( 5108 )
Time: 27.05.2012 - 01:36:02.768

What do you think may be the reason, can you help me?

32-bit vs. 64-bit Multicharts? (i.e. the DLL has to match whatever version of Multicharts you are running).

Just a thought,
Guy

p.s. I've since upgraded to using VS2013 Community Edition to generate 64-bit DLLs to use with MC64. The same code above "still works", in addition to a PureBasic variant which generates the exact same output. I can post new/updated sources for both versions if anyone is interested...

Follow me on Twitter Reply With Quote
Thanked by:
  #8 (permalink)
 rosasurfer 
Sofia Bulgaria
 
Experience: Intermediate
Platform: MetaTrader, MultiCharts
Trading: Forex, ES, GC, strange synthetic creatures
Posts: 40 since Nov 2014
Thanks Given: 41
Thanks Received: 34


Fu510n View Post
...function prototypes need to be defined as "__stdcall" rather than "__cdecl" but MC was unable to locate the functions ... due to the mangling
that occurred by declaring the functions as "__stdcall" (e.g. bad_function( int ) is exposed as _bad_function@4).
...
I wrote a quickee C/C++ test harness using "__cdecl" (on Visual Studio 2010) that others may find helpful. I'd still be interested in hearing
if anyone has been able to create and call DLLs by defining functions using "__stdcall"...

There are two ways to solve the mangling problem.

1) With DEF file: export the function names via a DEF file, there you can name them whatever you want. Specify the functions by ordinal numbers.

2) Without DEF file: Use linker comments. A lot of people will not like it but it's the simpliest way. The pragma statements belong anywhere in the function body.

Both ways work with VS2008 Pro, I can't test with later versions here but it should do.

Peter

 
Code
                            
//#define EXPORT extern "C" __declspec(dllexport)                         // standard way, we don't use it here

#define EXPORT   comment(linker, "/EXPORT:"__FUNCTION__"="__FUNCDNAME__)  // export unmangled names w/o DEF file

int WINAPI GetLastWin32Error() {  // WINAPI translates to __stdcall
   
return(GetLastError());
   
#pragma EXPORT

Resulting DLL in PE Explorer:


Reply With Quote
Thanked by:
  #9 (permalink)
 
Fu510n's Avatar
 Fu510n 
Suffield, CT
 
Experience: Advanced
Platform: MC, TS, Python, Rust
Broker: IB, IQFeed, TS, Kraken
Trading: ES, NQ, RTY, YM, CL, RB, 6E
Frequency: Several times daily
Duration: Seconds
Posts: 144 since Oct 2009
Thanks Given: 902
Thanks Received: 143


Fu510n View Post
32-bit vs. 64-bit Multicharts? (i.e. the DLL has to match whatever version of Multicharts you are running).

Just a thought,
Guy

p.s. I've since upgraded to using VS2013 Community Edition to generate 64-bit DLLs to use with MC64. The same code above "still works", in addition to a PureBasic variant which generates the exact same output. I can post new/updated sources for both versions if anyone is interested...

I received a request for the 64-bit PureBasic (5.31) source from another futures.io (formerly BMT) member, so I'll embed below...

MC64DLLTest.pb
 
Code
;
; ------------------------------------------------------------
;
;   PureBasic - DLL example file
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;
; This example is a skeleton to build easely a DLL using PureBasic
; The dll is created in the 'Compilers' directory, under the
; 'purebasic.dll' name. An associated '.lib' is generated to use
; with VisualC++.
;
;
; Rules to follow:
;   - Never write code outside a procedure, except for variables
;   or structure declaration.
;   
;   - DirectX Init routines must not be initialized in the the
;   AttachProcess() procedure
;   
;   - There is 4 procedures automatically called: AttachProcess(),
;   DetachProcess(), AttachThread() and DetachThread(). If you don't
;   need them, just remove them.
;

#TESTDLL = 0

CompilerIf #TESTDLL = 0

  CompilerIf #PB_Compiler_OS = #PB_OS_Windows

    ; These 4 procedures are Windows specific
    ;

    ; This procedure is called once, when the program loads the library
    ; for the first time. All init stuffs can be done here (but not DirectX init)
    ;
    ProcedureDLL AttachProcess(Instance)
    EndProcedure
  
    ; Called when the program release (free) the DLL
    ;
    ProcedureDLL DetachProcess(Instance)
    EndProcedure
  
    ; Both are called when a thread in a program call or release (free) the DLL
    ;
    ProcedureDLL AttachThread(Instance)
    EndProcedure
  
    ProcedureDLL DetachThread(Instance)
    EndProcedure

  CompilerEndIf

  ; Real code start here..
  ;
  ProcedureDLL EasyRequester(Message$)
    MessageRequester("EasyRequester !", Message$)
  EndProcedure

  ProcedureDLL.i bad_function( v.i )
    ProcedureReturn 123
  EndProcedure

  ProcedureCDLL.i good_function( v.i )
    ProcedureReturn 456
  EndProcedure

  ProcedureCDLL.b test_byte( b.b )
    ProcedureReturn b.b * 2
  EndProcedure

  ProcedureCDLL.c test_char( b.c )
    ProcedureReturn b.c
  EndProcedure

  ProcedureCDLL.s test_lpstr( s.s )
    ProcedureReturn s.s
  EndProcedure

  ProcedureCDLL.w test_word( w.w )
     ProcedureReturn w.w
  EndProcedure

  ProcedureCDLL.l test_dword( dw.l )
    ProcedureReturn dw.l
  EndProcedure

  ProcedureCDLL test_bool( b.b )
    ProcedureReturn b.b
  EndProcedure

  ProcedureCDLL.i test_int( i.i )
    ProcedureReturn i.i * 2
   EndProcedure

  ProcedureCDLL.l test_long( l.l )
    ProcedureReturn l.l * 2
  EndProcedure

  ProcedureCDLL.f test_float( f.f )
    ProcedureReturn f.f
  EndProcedure

  ProcedureCDLL.d test_double( d.d )
    ProcedureReturn d.d
  EndProcedure

CompilerElse

  If OpenLibrary(0, "MC64DLLTest.dll") Or OpenLibrary(0, "MC64DLLTest.so")
    CallFunction(0, "EasyRequester", @"Hello World!")  
  EndIf

CompilerEndIf

...and the EasyLanguage MC source that calls the above DLL...
 
Code
// Fu510nDLLTest - MultiCharts DLL test harness (writes output to Output window)

vars:
	int idx( 0 ),
	int n( 0 ),
	float f( 0.0 ),
	double d1( 0.0 ),
	s1( "string" ),
	s2( "" );

array:
	nArray[9]( 0 );

DefineDLLFunc: "MC64DLLTest.dll", byte,   "test_byte",   byte;   // 1 byte integer
DefineDLLFunc: "MC64DLLTest.dll", char,   "test_char",   char;   // 1 byte integer
DefineDLLFunc: "MC64DLLTest.dll", word,   "test_word",   word;   // 2 byte unsigned integer
DefineDLLFunc: "MC64DLLTest.dll", dword,  "test_dword",  dword;  // 4 byte unsigned integer
DefineDLLFunc: "MC64DLLTest.dll", bool,   "test_bool",   bool;   // 4 byte boolean
DefineDLLFunc: "MC64DLLTest.dll", int,    "test_int",    int;    // 4 byte signed integer
DefineDLLFunc: "MC64DLLTest.dll", long,   "test_long",   long;   // 4 byte signed integer
DefineDLLFunc: "MC64DLLTest.dll", float,  "test_float",  float;  // 4 byte floating point
DefineDLLFunc: "MC64DLLTest.dll", double, "test_double", double; // 8 byte floating point
DefineDLLFunc: "MC64DLLTest.dll", LPSTR,  "test_lpstr",  LPSTR;  // pointer to a char

once begin

	nArray[0] = 0;
	nArray[1] = 127;
	nArray[2] = 128;
	nArray[3] = 255;
	nArray[4] = -1;
	nArray[5] = 256;
	nArray[6] = 65536;
	nArray[7] = 65536*256;
	nArray[8] = 65536*65536;

	ClearDebug();

	for idx = 0 to 5 begin
		n = test_byte( nArray[idx] );
		MessageLog( "test_byte( ", nArray[idx]:0:0, " )=[ ", n:0:0, " ]" );
	end;

	MessageLog( "" );

	for idx = 0 to 5 begin
		n = test_char( nArray[idx] );
		MessageLog( "test_char( ", nArray[idx]:0:0, " )=[ ", n:0:0, " ]" );
	end;

	MessageLog( "" );

	s2 = test_lpstr( s1 );
	MessageLog( "test_lpstr( ", s1, " )=[ ", s2 , " ]" );

	MessageLog( "" );

	for idx = 0 to 6 begin
		n = test_word( nArray[idx] );
		MessageLog( "test_word( ", nArray[idx]:0:0, " )=[ ", n:0:0, " ]" );
	end;

	MessageLog( "" );

	for idx = 0 to 8 begin
		n = test_dword( nArray[idx] );
		MessageLog( "test_dword( ", nArray[idx]:0:0, " )=[ ", n:0:0, " ]" );
	end;

	MessageLog( "" );

	MessageLog( "test_bool( False )=[ ", test_bool( False ), " ]" );
	MessageLog( "test_bool( True )=[ ", test_bool( True ), " ]" );

	MessageLog( "" );

	nArray[8] = 65536*32768-1;
	nArray[9] = -(65536*32768);

	for idx = 0 to 9 begin
		n = test_int( nArray[idx] );
		MessageLog( "test_int( ", nArray[idx]:0:0, " )=[ ", n:0:0, " ]" );
	end;

	MessageLog( "" );

	for idx = 0 to 9 begin
		n = test_long( nArray[idx] );
		MessageLog( "test_long( ", nArray[idx]:0:0, " )=[ ", n:0:0, " ]" );
	end;

	MessageLog( "" );

	f = test_float( 123456.123456 );
	MessageLog( "test_float( ", 123456.123456:8:8, " )=[ ", f:8:8, " ]" );

	MessageLog( "" );

	d1 = test_double( 12345678.12345678 );
	MessageLog( "test_double( ", 12345678.12345678:8:8, " )=[ ", d1:8:8, " ]" );

end;

...which outputs...
 
Code
test_byte( 0 )=[ 0 ]
test_byte( 127 )=[ 254 ]
test_byte( 128 )=[ 0 ]
test_byte( 255 )=[ 254 ]
test_byte( -1 )=[ 254 ]
test_byte( 256 )=[ 0 ]

test_char( 0 )=[ 0 ]
test_char( 127 )=[ 127 ]
test_char( 128 )=[ -128 ]
test_char( 255 )=[ -1 ]
test_char( -1 )=[ -1 ]
test_char( 256 )=[ 0 ]

test_lpstr( string )=[ string ]

test_word( 0 )=[ 0 ]
test_word( 127 )=[ 127 ]
test_word( 128 )=[ 128 ]
test_word( 255 )=[ 255 ]
test_word( -1 )=[ 65535 ]
test_word( 256 )=[ 256 ]
test_word( 65536 )=[ 0 ]

test_dword( 0 )=[ 0 ]
test_dword( 127 )=[ 127 ]
test_dword( 128 )=[ 128 ]
test_dword( 255 )=[ 255 ]
test_dword( -1 )=[ 4294967295 ]
test_dword( 256 )=[ 256 ]
test_dword( 65536 )=[ 65536 ]
test_dword( 16777216 )=[ 16777216 ]
test_dword( 4294967296 )=[ 0 ]

test_bool( False )=[ FALSE ]
test_bool( True )=[ TRUE ]

test_int( 0 )=[ 0 ]
test_int( 127 )=[ 254 ]
test_int( 128 )=[ 256 ]
test_int( 255 )=[ 510 ]
test_int( -1 )=[ -2 ]
test_int( 256 )=[ 512 ]
test_int( 65536 )=[ 131072 ]
test_int( 16777216 )=[ 33554432 ]
test_int( 2147483647 )=[ -2 ]
test_int( -2147483648 )=[ 0 ]

test_long( 0 )=[ 0 ]
test_long( 127 )=[ 254 ]
test_long( 128 )=[ 256 ]
test_long( 255 )=[ 510 ]
test_long( -1 )=[ -2 ]
test_long( 256 )=[ 512 ]
test_long( 65536 )=[ 131072 ]
test_long( 16777216 )=[ 33554432 ]
test_long( 2147483647 )=[ -2 ]
test_long( -2147483648 )=[ 0 ]

test_float( 123456.12345600 )=[ 123456.12500000 ]

test_double( 12345678.12345678 )=[ 12345678.12345678 ]

Follow me on Twitter Reply With Quote
Thanked by:
  #10 (permalink)
 hughesfleming 
Sliema+Sliema/Malta
 
Experience: None
Platform: Multicharts, Proprietary
Broker: IB,IQFeed,Barcharts.com
Trading: Stocks,Futures
Posts: 40 since Mar 2014
Thanks Given: 87
Thanks Received: 20


Thanks!

Best wishes,


Alex

Reply With Quote




Last Updated on August 6, 2015


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts