Solved

How to fix then not value in array

Posted on 2012-03-27
27
601 Views
Last Modified: 2012-04-02
function splitTxt(stringGet: PChar; select: integer): TStringList; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  // Define a string list object, and point our variable at it
  TextName := TStringList.Create;

  // Now add some cars to our list - using the DelimitedText property
  // with overriden control variables
  TextName.Delimiter := ',';        // Each list item will be blank separated
  //TextName.QuoteChar := '|';        // And each item will be quoted with |'s
  TextName.DelimitedText := stringGet;

  // Free up the list object
  if(TextName[select] <> '') then
    begin
         Result := TStringList(TextName[select]);
    end;
  else
    begin
         Result := TStringList(0);
    end;

  TextName.Free;
end; 

Open in new window


how to fix bug about not value in array

i mean

splitTxt("1",0)  => 1
splitTxt("1",1)  => 0
splitTxt("1",2)  => 0

splitTxt("1,2,3",0)  => 1
splitTxt("1,2,3",1)  => 2

or

splitTxt("1,2",3)  => 0
0
Comment
Question by:XSoFTz
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 10
  • 2
  • +1
27 Comments
 
LVL 45

Expert Comment

by:aikimark
ID: 37772791
You need to check for a select value greater than the highest index of items in the TStringList (=.count-1)
You will need to add something like the following before line 15:
If TextName.Count-1 < select Then

Open in new window

0
 
LVL 19

Expert Comment

by:Thommy
ID: 37775171
Have modified your function to return a simple string and to use Try..except for returning an empty string, if passed variable stringGet is empty...

function splitTxt(stringGet: PChar; select: integer):String;
var
  TextName: TStringList;            // Define our string list variable
begin
  // Define a string list object, and point our variable at it
  TextName := TStringList.Create;

  // Now add some cars to our list - using the DelimitedText property
  // with overriden control variables
  TextName.Delimiter := ',';        // Each list item will be blank separated
  //TextName.QuoteChar := '|';        // And each item will be quoted with |'s
  TextName.DelimitedText := stringGet;

  try
    // Free up the list object
    if(TextName[select] <> '') then
      Result := TextName[select];
  except
    Result:='';
  end;

  FreeAndNil(TextName);
end;

Open in new window

0
 

Author Comment

by:XSoFTz
ID: 37775223
not work

but i make dll file

program say


2012.03.28 13:43:29      testDLL EURUSDr,H1: initialized
2012.03.28 13:43:29      testDLL EURUSDr,H1: Return Dll :
2012.03.28 13:43:29      testDLL EURUSDr,H1: function 'splitTxt2' call from dll 'aiDll.dll' critical error c0000005 at 063B2A21.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 19

Expert Comment

by:Thommy
ID: 37775411
I didn't know that your question applies to a DLL!!!

Test my function in a normal exe application, and you will see that it works fine.

Then you can implement it into your DLL by changing necessary parameter types...
0
 

Author Comment

by:XSoFTz
ID: 37775420
how ?
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37775506
To tell you "how", it is necessary that you post the relevant code parts of your dll and your dll test program!!!

Besides that, you are getting a critical error when calling function SplitText2!!!

What's the name of your DLL function, SplitText2 or simply SplitText???
0
 

Author Comment

by:XSoFTz
ID: 37775526
library aiDll;

{$mode objfpc}
{$H+}

uses
  Classes,
  SysUtils, synacode, httpsend;

// Function Split
function splitTxt(stringGet: PChar; select: integer): TStringList; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  // Define a string list object, and point our variable at it
  TextName := TStringList.Create;

  // Now add some cars to our list - using the DelimitedText property
  // with overriden control variables
  TextName.Delimiter := ',';        // Each list item will be blank separated
  //TextName.QuoteChar := '|';        // And each item will be quoted with |'s
  TextName.DelimitedText := stringGet;

  // Free up the list object
  Result := TStringList(TextName[select]);
  TextName.Clear;
  TextName.Free;
end;

function splitTxt2(stringGet: PChar; select: integer):String; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  TextName := TStringList.Create;
  TextName.Delimiter := ',';
  TextName.DelimitedText := stringGet;

  try
    // Free up the list object
    if(TextName[select] <> '') then
      Result := TextName[select];
  except
    Result:='0';
  end;

  FreeAndNil(TextName);
end;     

exports
  splitTxt,
  splitTxt2;

begin
end.   

Open in new window


splitTxt it old version
splitTxt it u version

not work both

and i use mt4

http://www.metatrader4.com/ program

thankyou
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37775619
I never used mt4 and it would be much work for me to learn the ropes.
Too much for just 200 points!!!

Therefore, can you please tell me how you manage to call function SplitTxt from mt4 or can you even post part of code which calls function SplitTxt from mt4???

Which variable types does mt4 expect???

I wonder why you have defined TStringList as return parameter for your original function SplitTxt?? It seems to be pointless or do you have areason for this obscure definition?
0
 

Author Comment

by:XSoFTz
ID: 37775628
sory i not know point system?

#import "aiDll.dll"
   // declare the imported function exactly as it is exported by the dll
   string splitTxt(string text, int select);
   string splitTxt2(string text, int select);
#import

int init(){
   string data[6];
   
   /*
   string s = foo(42.3, "Worlds");
   Print("Return Dll : "+s);
   */
   
   string k = splitTxt("1,20,50",0);
   Print("Return Dll : "+k);

int start(){
}

Open in new window

0
 
LVL 37

Accepted Solution

by:
Geert Gruwez earned 200 total points
ID: 37776097
You are making wrong assumption in your code
have you tried this
  string k = splitTxt("1,20,0,50",5);

> result string k = "0"
which is completely wrong
either raise an exception, or return an empty string when nothing is found

and *always* use try finally to contain memory leaks !

one other thing > you comment the use of control variables
>> you don't have any

// Function Split 
// Find select item in comma separated string (item = 0 to n-1)
function splitTxt(stringGet: PChar; select: integer): PChar; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  Result := '';
  // Define a string list object, and point our variable at it
  TextName := TStringList.Create;
  try
    TextName.Delimiter := ',';        // Each list item will be comma separated
    TextName.StrictDelimiter := True; // Only commas and not spaces
    TextName.DelimitedText := stringGet;
    
    // Find the item
    if (select >= 0) and (select < TextName.Count) then 
      Result := TextName[select];
  finally
    TextName.Free;
  end;
end;

Open in new window


your mt4 code can not handle TStringList as a return type, only PChar
consider raising an exception when select is out of range or item not found
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37776165
This is a detailed guide for creating metatrade extensions (dll)...
Guide to writing a DLL for MQL5 in Delphi

Have a look at chapter  "3. Passing Parameters to the Function and Returned Values". It states that you should use PWideChar as return parameter for your function SplitTxt!!!

Use PWideChar or PChar as Geert_Gruwez mentioned in his post:

function splitTxt2(stringGet: PWideChar; select: integer):PWideChar; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  TextName := TStringList.Create;
  TextName.Delimiter := ',';
  TextName.DelimitedText := stringGet;

  try
    // Free up the list object
    if(TextName[select] <> '') then
      Result := TextName[select];
  except
    Result:='0';
  end;

  FreeAndNil(TextName);
end;

Open in new window

0
 

Author Comment

by:XSoFTz
ID: 37776283
aiDll.pas(48,25) Error: Incompatible types: got "AnsiString" expected "PChar"

it error ..

i use lazarus devalopment

and then i need return to double i can it ?

i use mt4 not mt5

broker not support mt5
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 37776304
> XSoFTz
if you want help you'll have to start and explain your problem in detail !


if i put a question in here as follows:
"Help, I Error"

Our question will be: "What ?" That makes no sense

It may be very frustrating to you when you don't get the answer you want.
Good communication is the basis for getting a good answer.
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37776378
You will not suffer any harm reading the Guide to writing a DLL for MQL5 in Delphi !!!
Basically the principles are the same for mt5 and mt4.

OK, probably mt4 cannot handle PWideChar.
Try the same with PCHAR...

function splitTxt2(stringGet: PChar; select: integer):PChar; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  TextName := TStringList.Create;
  TextName.Delimiter := ',';
  TextName.DelimitedText := stringGet;

  try
    // Free up the list object
    if(TextName[select] <> '') then
      Result := TextName[select];
  except
    Result:='0';
  end;

  FreeAndNil(TextName);
end;

Open in new window

0
 

Author Comment

by:XSoFTz
ID: 37776385
>Geert_Gruwez

So sorry

now i devalopment EA (Expert Advisor) on MT4 ( MetaTrader 4 Only)  and i make function spliteText but not work

and i use code pascal by lazarus IDE. i not know mean Delphi IDE
but i need help

in MT4 Code

#import "aiDll.dll"
   // declare the imported function exactly as it is exported by the dll
   string splitTxt(string text, int select);
   string splitTxt2(string text, int select);
#import

int init(){
   
   string k = splitTxt("1,20,50",0);
   Print("Return Dll : "+k);
}

int start(){
}

Open in new window


in dll by pascal (Lazarus)

library aiDll;

{$mode objfpc}
{$H+}

uses
  Classes,
  SysUtils, synacode, httpsend;

// Function Split
function splitTxt(stringGet: PChar; select: integer): TStringList; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  // Define a string list object, and point our variable at it
  TextName := TStringList.Create;

  // Now add some cars to our list - using the DelimitedText property
  // with overriden control variables
  TextName.Delimiter := ',';        // Each list item will be blank separated
  //TextName.QuoteChar := '|';        // And each item will be quoted with |'s
  TextName.DelimitedText := stringGet;

  // Free up the list object
  Result := TStringList(TextName[select]);
  TextName.Clear;
  TextName.Free;
end;

function splitTxt2(stringGet: PChar; select: integer):String; stdcall;
var
  TextName: TStringList;            // Define our string list variable
begin
  TextName := TStringList.Create;
  TextName.Delimiter := ',';
  TextName.DelimitedText := stringGet;

  try
    // Free up the list object
    if(TextName[select] <> '') then
      Result := TextName[select];
  except
    Result:='0';
  end;

  FreeAndNil(TextName);
end;     

exports
  splitTxt,
  splitTxt2;

begin
end.   

Open in new window


i not know pass parameter u can help me ?
0
 

Author Comment

by:XSoFTz
ID: 37776416
PChar it not work i can't make dll

lazarus error log


aiDll.pas(48,25) Error: Incompatible types: got "AnsiString" expected "PWideChar"
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37776433
Why not simply trying AnsiString and PAnsiString...

function splitTxt(stringGet: AnsiString; select: integer): AnsiString; stdcall;
0
 

Author Comment

by:XSoFTz
ID: 37776481
>aikimark

what lazarus zone ?

>Thommy
i try it but not work. i lite pascal code.
it frist project my code in pascal
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37780383
@aikimark
You can additionally put it into Lazarus zone, but please leave it in Delphi zone,too...

@XSoFTz
Can you please post your error message when using PWideChar???
0
 

Author Comment

by:XSoFTz
ID: 37781535
>Thommy

thank you for u help now i can compile work
But some time program it hang , i not know why hange

i think about i coding wrong ?
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37794781
If your program hangs, it's surely not inside the function SplitTxt!!!

Therefore I consider this question as solved and you're advised to post a new question with all relevant information...
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37794962
Have you ever heard of "Splitting Points"???
0
 

Author Comment

by:XSoFTz
ID: 37794968
How To ?
0
 
LVL 19

Expert Comment

by:Thommy
ID: 37798622
How to accept multiple solutions and split points to the experts...
http://www.experts-exchange.com/help/viewHelpPage.jsp?helpPageID=24
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

724 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