views:

145

answers:

3

Hi everyone,

this is my first post here, so please be gentle if I am missing something out ;-)

I am having a compilation problem with my code in Delphi 2006. I am using a static String array:

fsi_names : array [0..FSI_NUM_VARS-1] of string;

In a procedure I call at the start of the program, I assign values to this array. This code is automatically generated by a script that I wrote. It consists of lines similar to the next one:

fsi_names[idFSI_FLIGHT_PATH_ANGLE] := 'FSI_FLIGHT_PATH_ANGLE';

There are overall around 2000 elements to be assigned in this array. I couldn't find out the magic number where the compiler dies, but it works with 1853 and doesn't with 2109.

The thing is that I need this array to convert an ID (which is the index to the array) to a name as a string for various applications.

I know that if I would split the list of assignments and put the parts into different procedures, then it works out. But since the code is auto-generated and changes often, this method is not quite comfortable.

I also thought about putting the contents into a file and read it at runtime, but I would rather keep the number of files I have to ship to a minimum. Also, I would like to protect the contents from the average user, so that he doesn't mess with it.

Do you have an idea how I could either overcome the limitation of the compiler, or change my code to achieve my goal?

Help is very much appreciated...

Greetings from Germany

Flo

+3  A: 

If I were you, I would create a simple ASCII text file with the identifiers, so that line idFSI_FLIGHT_PATH_ANGLE + 1 of the file contains the string "FSI_FLIGHT_PATH_ANGLE". Then I would add this file to the application's resources. By doing so, the data will be included in the EXE, and you can easily read the data at run-time:

function GetNthString(const N: integer): string;
var
  RS: TResourceStream;
begin
  RS := TResourceStream.Create(hInstance, 'NAMEOFRESOURCE', RT_RCDATA);
  with TStringList.Create do
    try
      LoadFromStream(RS);
      result := Strings[N];
    finally
      Free;
    end;
  RS.Free;
end;
Andreas Rejbrand
At first glance, this looks like a feasible solution. I would have to review Resources though -- can you maybe tell me whether I have to include this text file manually when it has changed, e.g. with a resource editor, or if it is read from my hard disk every time I build my program? As mentioned, these strings change often, so I would like to do it all automatically.Thank you
Flo
Delphi 2009 has a very nice resource manager, so that the newest version of the file is automatically included when you build your project. Unfortunately, however, I believe that the resource manager was new to Delphi 2009...
Andreas Rejbrand
Damn... I am stuck with 2006 for a while due to components that are allergic to Unicode... Does anyone know if there is a comfortable way with the 2006 version?
Flo
A: 

Alternative is using dynamic array

from
fsi_names : array [0..FSI_NUM_VARS-1] of string;

to
fsi_names: array of string;
SetLength(fsi_names, FSI_NUM_VARS);

Cheers

APZ28
To be honest, I don't see the point where this solves my problem. I would still have to assign a large number of string literals. Or did I get you wrong?
Flo
This has nothing to do with the problem. The compiler is choking on the huge number of constants in one method. The Delphi compiler does have some limits that are beyond what one should ever write but occasionally they can become an issue with autogenerated stuff.
Loren Pechtel
+2  A: 

I FOUND A SOLUTION!

If I initialize my array at the point where I define it, then the compiler does not spit out the error message:

const
  fsi_names : array [0..FSI_NUM_VARS-1] of string = (
    'NAME 0',
    'NAME 1',
    ...
    'LAST NAME'
    );

As far as I can tell, there is no limit regarding the number of string literals if I do it like that.

Thank you so much for your ideas, the one by mj2008 was most helpful!

Have a nice day

Flo

Flo
I know it's pretty lame to answer one's own question -- but the above was the solution that solved the problem the most elegant way, at least for my application. Notice that I am using a CONSTANT array, if you need to use a VARIABLE array Andreas' solution seems to be the way to go.
Flo