Solved

How to fix then not value in array

Posted on 2012-03-27
27
600 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
Industry Leaders: 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

733 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