mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 12:39:09 +02:00
* android: cwstring: Fixed crash on unload in some cases. Allow ICU usage from other units.
git-svn-id: trunk@34345 -
This commit is contained in:
parent
4a9eaf5317
commit
b10e4aa27b
@ -38,6 +38,8 @@ type
|
|||||||
var
|
var
|
||||||
hlibICU: TLibHandle;
|
hlibICU: TLibHandle;
|
||||||
hlibICUi18n: TLibHandle;
|
hlibICUi18n: TLibHandle;
|
||||||
|
LibVer: ansistring;
|
||||||
|
|
||||||
ucnv_open: function (converterName: PAnsiChar; var pErrorCode: UErrorCode): PUConverter; cdecl;
|
ucnv_open: function (converterName: PAnsiChar; var pErrorCode: UErrorCode): PUConverter; cdecl;
|
||||||
ucnv_close: procedure (converter: PUConverter); cdecl;
|
ucnv_close: procedure (converter: PUConverter); cdecl;
|
||||||
ucnv_setSubstChars: procedure (converter: PUConverter; subChars: PAnsiChar; len: byte; var pErrorCode: UErrorCode); cdecl;
|
ucnv_setSubstChars: procedure (converter: PUConverter; subChars: PAnsiChar; len: byte; var pErrorCode: UErrorCode); cdecl;
|
||||||
@ -456,44 +458,43 @@ end;
|
|||||||
|
|
||||||
procedure UnloadICU;
|
procedure UnloadICU;
|
||||||
begin
|
begin
|
||||||
if hlibICUi18n <> 0 then begin
|
if DefColl <> nil then
|
||||||
if DefColl <> nil then
|
ucol_close(DefColl);
|
||||||
ucol_close(DefColl);
|
if DefConv <> nil then
|
||||||
UnloadLibrary(hlibICUi18n);
|
ucnv_close(DefConv);
|
||||||
hlibICUi18n:=0;
|
if LastConv <> nil then
|
||||||
end;
|
ucnv_close(LastConv);
|
||||||
|
|
||||||
if hlibICU <> 0 then begin
|
if hlibICU <> 0 then begin
|
||||||
if DefConv <> nil then
|
|
||||||
ucnv_close(DefConv);
|
|
||||||
if LastConv <> nil then
|
|
||||||
ucnv_close(LastConv);
|
|
||||||
UnloadLibrary(hlibICU);
|
UnloadLibrary(hlibICU);
|
||||||
hlibICU:=0;
|
hlibICU:=0;
|
||||||
end;
|
end;
|
||||||
|
if hlibICUi18n <> 0 then begin
|
||||||
|
UnloadLibrary(hlibICUi18n);
|
||||||
|
hlibICUi18n:=0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetIcuProc(const Name: AnsiString; out ProcPtr; libId: longint = 0): boolean; [public, alias: 'CWSTRING_GET_ICU_PROC'];
|
||||||
|
var
|
||||||
|
p: pointer;
|
||||||
|
hLib: TLibHandle;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
if libId = 0 then
|
||||||
|
hLib:=hlibICU
|
||||||
|
else
|
||||||
|
hLib:=hlibICUi18n;
|
||||||
|
if hLib = 0 then
|
||||||
|
exit;
|
||||||
|
p:=GetProcedureAddress(hlib, Name + LibVer);
|
||||||
|
if p = nil then
|
||||||
|
exit;
|
||||||
|
pointer(ProcPtr):=p;
|
||||||
|
Result:=True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure LoadICU;
|
procedure LoadICU;
|
||||||
var
|
|
||||||
LibVer: ansistring;
|
|
||||||
|
|
||||||
function _GetProc(const Name: AnsiString; out ProcPtr; hLib: TLibHandle = 0): boolean;
|
|
||||||
var
|
|
||||||
p: pointer;
|
|
||||||
begin
|
|
||||||
if hLib = 0 then
|
|
||||||
hLib:=hlibICU;
|
|
||||||
p:=GetProcedureAddress(hlib, Name + LibVer);
|
|
||||||
if p = nil then begin
|
|
||||||
// unload lib on failure
|
|
||||||
UnloadICU;
|
|
||||||
Result:=False;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
pointer(ProcPtr):=p;
|
|
||||||
Result:=True;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
const
|
const
|
||||||
ICUver: array [1..9] of ansistring = ('3_8', '4_2', '44', '46', '48', '50', '51', '53', '55');
|
ICUver: array [1..9] of ansistring = ('3_8', '4_2', '44', '46', '48', '50', '51', '53', '55');
|
||||||
TestProcName = 'ucnv_open';
|
TestProcName = 'ucnv_open';
|
||||||
@ -502,8 +503,14 @@ var
|
|||||||
i: longint;
|
i: longint;
|
||||||
s: ansistring;
|
s: ansistring;
|
||||||
begin
|
begin
|
||||||
|
{$ifdef android}
|
||||||
hlibICU:=LoadLibrary('libicuuc.so');
|
hlibICU:=LoadLibrary('libicuuc.so');
|
||||||
hlibICUi18n:=LoadLibrary('libicui18n.so');
|
hlibICUi18n:=LoadLibrary('libicui18n.so');
|
||||||
|
{$else}
|
||||||
|
hlibICU:=LoadLibrary('icuuc40.dll');
|
||||||
|
hlibICUi18n:=LoadLibrary('icuin40.dll');
|
||||||
|
LibVer:='_4_0';
|
||||||
|
{$endif android}
|
||||||
if (hlibICU = 0) or (hlibICUi18n = 0) then begin
|
if (hlibICU = 0) or (hlibICUi18n = 0) then begin
|
||||||
UnloadICU;
|
UnloadICU;
|
||||||
exit;
|
exit;
|
||||||
@ -540,33 +547,39 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not _GetProc('ucnv_open', ucnv_open) then exit;
|
if not GetIcuProc('ucnv_open', ucnv_open) then exit;
|
||||||
if not _GetProc('ucnv_close', ucnv_close) then exit;
|
if not GetIcuProc('ucnv_close', ucnv_close) then exit;
|
||||||
if not _GetProc('ucnv_setSubstChars', ucnv_setSubstChars) then exit;
|
if not GetIcuProc('ucnv_setSubstChars', ucnv_setSubstChars) then exit;
|
||||||
if not _GetProc('ucnv_setFallback', ucnv_setFallback) then exit;
|
if not GetIcuProc('ucnv_setFallback', ucnv_setFallback) then exit;
|
||||||
if not _GetProc('ucnv_fromUChars', ucnv_fromUChars) then exit;
|
if not GetIcuProc('ucnv_fromUChars', ucnv_fromUChars) then exit;
|
||||||
if not _GetProc('ucnv_toUChars', ucnv_toUChars) then exit;
|
if not GetIcuProc('ucnv_toUChars', ucnv_toUChars) then exit;
|
||||||
if not _GetProc('u_strToUpper', u_strToUpper) then exit;
|
if not GetIcuProc('u_strToUpper', u_strToUpper) then exit;
|
||||||
if not _GetProc('u_strToLower', u_strToLower) then exit;
|
if not GetIcuProc('u_strToLower', u_strToLower) then exit;
|
||||||
if not _GetProc('u_strCompare', u_strCompare) then exit;
|
if not GetIcuProc('u_strCompare', u_strCompare) then exit;
|
||||||
if not _GetProc('u_strCaseCompare', u_strCaseCompare) then exit;
|
if not GetIcuProc('u_strCaseCompare', u_strCaseCompare) then exit;
|
||||||
|
|
||||||
if not _GetProc('u_errorName', u_errorName) then exit;
|
if not GetIcuProc('u_errorName', u_errorName) then exit;
|
||||||
|
|
||||||
if not _GetProc('ucol_open', ucol_open, hlibICUi18n) then exit;
|
if not GetIcuProc('ucol_open', ucol_open, 1) then exit;
|
||||||
if not _GetProc('ucol_close', ucol_close, hlibICUi18n) then exit;
|
if not GetIcuProc('ucol_close', ucol_close, 1) then exit;
|
||||||
if not _GetProc('ucol_strcoll', ucol_strcoll, hlibICUi18n) then exit;
|
if not GetIcuProc('ucol_strcoll', ucol_strcoll, 1) then exit;
|
||||||
if not _GetProc('ucol_setStrength', ucol_setStrength, hlibICUi18n) then exit;
|
if not GetIcuProc('ucol_setStrength', ucol_setStrength, 1) then exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
oldm: TUnicodeStringManager;
|
||||||
initialization
|
initialization
|
||||||
|
GetUnicodeStringManager(oldm);
|
||||||
DefaultSystemCodePage:=GetStandardCodePage(scpAnsi);
|
DefaultSystemCodePage:=GetStandardCodePage(scpAnsi);
|
||||||
DefaultUnicodeCodePage:=CP_UTF16;
|
DefaultUnicodeCodePage:=CP_UTF16;
|
||||||
LoadICU;
|
LoadICU;
|
||||||
SetCWideStringManager;
|
SetCWideStringManager;
|
||||||
|
{$ifdef android}
|
||||||
SetStdIOCodePages;
|
SetStdIOCodePages;
|
||||||
|
{$endif android}
|
||||||
|
|
||||||
finalization
|
finalization
|
||||||
|
SetUnicodeStringManager(oldm);
|
||||||
UnloadICU;
|
UnloadICU;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user