Solved

Tradestation and Dll

Posted on 2013-01-07
27
520 Views
Last Modified: 2013-12-12
I want to use C# to Get the Global Variables from the third party program Tradestation and process the data.
Declaration inTS is :

external:  "GlobalVariable.dll", int, "GV_GetInteger", int ;
external:  "GlobalVariable.dll", int, "GV_SetInteger", int, int ;
this GlobalVar.Dll is written in C++ ,but far behind my experience - so the question is if this is possible at all?  (the GlobalVar. is only working in realtime)
0
Comment
Question by:JojoR
  • 14
  • 11
27 Comments
 
LVL 42

Expert Comment

by:sedgwick
ID: 38751290
try this:

[DllImport(@"c:\<full-path>\GlobalVariable.dll")]
   private static int GV_GetInteger(int a);

[DllImport(@"c:\<full-path>\GlobalVariable.dll")]
   private static int GV_SetInteger(int a, int b);

Open in new window

0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38751295
now, once u set the full path of the dll, you can simply call the function from your managed code:

class Program
{
  [DllImport(@"c:\<full-path>\GlobalVariable.dll")]
   private static int GV_GetInteger(int a);

[DllImport(@"c:\<full-path>\GlobalVariable.dll")]
   private static int GV_SetInteger(int a, int b);

   static void Main(string[] args)
   {
       Console.WriteLine(GV_GetInteger(3));
       Console.WriteLine(GV_SetInteger(3,4));
   }
}

Open in new window

0
 

Author Comment

by:JojoR
ID: 38754311
thank you for answering.I'm not very good in programming so I miss the first part -
Try this ......
Do I have to build a extra class first of this part?

If I open a new console project only with your code class programm , then some references might missing , but I cannot add a reference to the GlobalVariable .
If I add using  System.Runtime.InteropServices; then error "ConsoleApplication.1.Program.GV_GetInteger(int)" is not declared abstract, extern or partial
and has to daclare text (my translation)
what do I miss?
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38754418
add extern keyword:

class Program
{
  [DllImport(@"c:\<full-path>\GlobalVariable.dll")]
   private static extern int GV_GetInteger(int a);

[DllImport(@"c:\<full-path>\GlobalVariable.dll")]
   private static extern int GV_SetInteger(int a, int b);

   static void Main(string[] args)
   {
       Console.WriteLine(GV_GetInteger(3));
       Console.WriteLine(GV_SetInteger(3,4));
   }
}

Open in new window

0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38754420
you need to add the reference System.Runtime.InteropServices.
0
 

Author Comment

by:JojoR
ID: 38755052
I've added using System.Runtime.InteropServices;now compiles without errors ,but then get:
Bad image format exeption HRESULT: 0x8007000B
make shure assembly is valid and path is correct
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38755715
try this:

class Program
{
  [DllImport(@"c:\<full-path>\GlobalVariable.dll",CallingConvention=CallingConvention.Cdecl)]
   private static extern int GV_GetInteger(int a);

[DllImport(@"c:\<full-path>\GlobalVariable.dll",CallingConvention=CallingConvention.Cdecl)]
   private static extern int GV_SetInteger(int a, int b);

   static void Main(string[] args)
   {
       Console.WriteLine(GV_GetInteger(3));
       Console.WriteLine(GV_SetInteger(3,4));
   }
}

Open in new window

0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38755793
an alternative is using win32api loadlibrary to dynamically load your dll:
    class Program
    {
        [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
        static extern int LoadLibrary(
            [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);

        [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
        static extern IntPtr GetProcAddress(int hModule,
            [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

        [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
        static extern bool FreeLibrary(int hModule);

        //declare delegates to convert pointer functions
        delegate int D_GV_GetInteger(int b);
        delegate int D_GV_SetInteger(int a, int b);

        static void Main(string[] args)
        {
            //load dll
            int hModule = LoadLibrary(@"c:\dlls\GlobalVariable.dll");
            if (hModule == 0) return;
            IntPtr intPtrGetInteger = GetProcAddress(hModule, "GV_GetInteger");
            IntPtr intPtrSetInteger = GetProcAddress(hModule, "GV_SetInteger");

            D_GV_GetInteger GV_GetInteger = (D_GV_GetInteger)Marshal.GetDelegateForFunctionPointer(intPtrGetInteger, typeof(D_GV_GetInteger));
            Console.WriteLine(GV_GetInteger(3));

            D_GV_SetInteger GV_SetInteger = (D_GV_SetInteger)Marshal.GetDelegateForFunctionPointer(intPtrSetInteger, typeof(D_GV_SetInteger));
            Console.WriteLine(GV_SetInteger(3, 4));
        }
    }

Open in new window

0
 

Author Comment

by:JojoR
ID: 38758163
Hello
First thank you for your efforts and assistance - we are getting closer.
Your first suggestion using calling convention leads to the same result as before:Bad image format exeption.Your second seemes to be better - no exeption thrown,compiling.
But then strange is that I added Console.ReadLine() after ConsoleWriteLine and it disappeares anyway - so I can not prove ,if there is a correct result .
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38758180
Can u debug your code and see if the function returns something?
0
 

Author Comment

by:JojoR
ID: 38758194
sorry my fault I forget to set the proper path to the dll , to fast. it works so far:
I get 3 for  the location( adress or whatever don't no how to describe exactly) the global var stores the values, but not the value itself.
I attach a description
Global-Variable-2.3.doc
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38761790
did you manage to call the functions of your dll successfully?
are you saying you are not satisfy with the function result?
i don't understand what's the doc u attached go to do with the question.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:JojoR
ID: 38762319
Sorry for confusing - I try to clear.The GV_Set has two parameters ,GV_Get only one.As far I understand ,the first par.stands for the location (pointer?), where the value (any variable) is stored (the second par).
If I call GV_Get(3) ,I receive the value(4) which is stored(in location 3) by a calculation made in Tradestation already - fetch it and process for further calcs in C#. ( then maybe sending it back or display in another form or sth.like this)
What I get now on the console is  " 3 " , so works perfect this far - but I need the values (4) ofcourse - which should deliver the ongoing realtime values running.
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38762361
what i meant by in my question is, whether the problem you are facing is technical or logical/business problem by the nature of the function.

it seems that the function doesn't do what it suppose to do, right?
if that is the matter than i can't really help you without having the code of the dll.

secondly, your initial question was how can you load the assembly and call the get/set functions from C# code, which i answered.
0
 

Author Comment

by:JojoR
ID: 38762408
I appreciate your efforts, ofcourse. Due to my limitations I try my best to explain , where the problem is. I attach the code.
Have problems with allowed extensions.renamed def to txt.I hope these two files are right.
GV23Code.cpp
GV23Def.txt
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38762476
sorry, i don't understand what is not working for you.
0
 

Author Comment

by:JojoR
ID: 38762831
In Tradestation I make calculations in one chart -> store result in GV_Set global var->  I can get (inside TS in another chart i.e.) these results - if I call GV_Get ,process the variables values further,display them etc.
What I wanted to achieve is to get these results(variables) which I set in Tradestation to ->
external application C# to process the data incoming in realtime.
what is working now is to get the location number where the Global Variable stores these results - but I need the values which are stored in this location, not only the location itself.

I hope this is clear now.
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38762997
ok, i understand.
before i get into solving your problem, can i ask why the global variables used in memory rather than from a file?

the reason i ask is that it's very unorthodox and not best practice to have one application access variables stored in a memory in another application with direct API.
if both application runs on the same environment or even on different machines but with access to each one, it's better to have the Tradestation which set those global variables, dump them to a file where your C# app can read them.

in this case, you can have the C# app get notification (triggered) whenever those variables are changed (via file watcher for instance).

this is better approach cause u don't tight your C# app with the dll's memory space.
let me know what you think of this approach, if it's make sense to you or if it's feasible to implement in your environment.
0
 

Author Comment

by:JojoR
ID: 38763080
interesting idea , but I do not know if processing is fast enough this way.Sometimes ther are several values within a second.But if this would be practicable, no problem
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38763100
how often the variables are being set?
the reading would be fast enough i imagine.

another question, who/how the C# app is being imitated?
is it running constantly and need to read these variables on specific intervals?
0
 

Author Comment

by:JojoR
ID: 38763132
between 1  to ~ 20(max) within one second

yes constantly to catch these incoming values as tight as possible - interval has to be checked
maybe 10 ms are fast enough
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 38763210
what those variables are used for by the C# app?
how are they being processed?
0
 

Author Comment

by:JojoR
ID: 38763245
this is not yet developed .Generally it's about " Tradespeed " , time intervals between the single trades that occurr in trading and how these changes and accumulations interfere the price movement - more generally just price and time
0
 
LVL 42

Accepted Solution

by:
sedgwick earned 500 total points
ID: 38763422
so we share the same "business", i work in forex company so i understand where you come from.

since time is a major factor here, i'd have your managed C++ dll invoke .net delegate from C# library.
basically it's a reverse mechanism of what you were initially wanted to implement.
so instead of having C# app which constantly reads the variables, you will have your managed C++ dll call directly your C# dll.

the best and easiest example i found on the internet is posted here:
Reverse P/Invoke

its fairly easy to implement, if you encounter any problems let me know and i'll guide you through.

cheers
0
 

Author Comment

by:JojoR
ID: 38764141
oops and I thought there would be an easy solution - so theoretically I need my C# dll with all calculations in it first and ready to go -
and then put  this Reverse mechanism into the existing .cpp GlobalVar code to call this     and call this then from Tradestation ? I will try to understand the concept .
Thanks again for everything you did so far
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

If you haven’t already, I encourage you to read the first article (http://www.experts-exchange.com/articles/18680/An-Introduction-to-R-Programming-and-R-Studio.html) in my series to gain a basic foundation of R and R Studio.  You will also find the …
The purpose of this article is to demonstrate how we can use conditional statements using Python.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now