问题
The situation is:
unit abc;
interface
resourcestring
aabbcc = 'my text here';
implementation
end.
From my application I received error code 'aabbcc'. Is possible to access with error code the resource name aabbcc ?
回答1:
I imagine you're asking for a function with the following signature and behavior:
function GetNamedResourceString(const Name: string): string;
Assert(GetNamedResourceString('aabbcc') = 'my text here');
Resource strings are stored in your program in a string-table resource, where each string has a numeric index. The named identifier you use in your program is not kept anywhere at run time. Therefore, there is no built-in way to take the text 'aabbcc'
and discover which string resource it's associated with.
However, there is a way to take the Delphi resourcestring
identifier in your code and discover its numeric ID. Type-cast the expression @aabbcc
to PResStringRec, and then read its Identifier
field. Look at LoadResString in System.pas to see how the RTL uses this information.
You could use the PResStringRec
values to build a TDictionary<string, PResStringRec> at run time, and then use that dictionary in implementing the hypothetical GetNamedResourceString
function outlined above.
NamedResources := TDictionary<string, PResStringRec>.Create;
NamedResources.Add('aabbcc', PResStringRec(@aabbcc));
function GetNamedResourceString(const Name: string): string;
begin
Result := LoadResString(NamedResources[Name]);
end;
If I were doing this for a real project, I would probably use a pre-build script to parse an input file to automatically generate the calls to NamedResources.Add
from the corresponding resourcestring
declarations.
回答2:
Your resourcestring
is compiled into a string table resource. These are identified by a numeric identifier. The compiler maintains a map between your declared resourcestring
instances, and the numeric identifiers. When you access a resourcestring
the compiler knows the numeric identifier, and emits code that uses that identifier. Essentially what you are hoping to do is to be able to map from the name of your resourcestring
and the numeric identifier. Unfortunately that map only exists during compilation. It is not contained in the executable.
Your only other hope would be for the compiler to generate RTTI information for resource strings. However, it does not do this, unless I am very much mistaken.
Given these constraints you are going to need to come up with your own mechanism to map between names and resource strings. One possibility is to avoid using the built-in resourcestring
, and manage the string table resources, and their identifiers, by your own mechanisms.
来源:https://stackoverflow.com/questions/29145598/delphi-how-can-i-find-a-resource-name-from-resourcestring-unit