On 14-09-2022 23:09, Rik van Kekem wrote:
On 14-09-2022 13:32, Petr Kolář wrote:

I‘ve founded, that iconv.dll failed on a 64 bit system.

It raised exception $C0000005 access violation.

It works fine on 32 bit.

It also states this in synaicnv.pas:
// Content: ICONV support for Win32, OS/2, Linux and .NET
So I guess Win64 isn't supported yet.

It is possible to create your own calls to iconv.dll (I tried) but you'll need to know the exact parameter structure (and that's where it goes wrong in synaicnv.pas).

BTW. Here is my working code of manually loading iconv.dll and calling iconv.

So the problems in synaicnv.pas are
*) the //IGNORE isn't supported anymore in newer versions
*) size_t needs to be UIntPtr (that one held me up a bit). I made it a psize_t (^size_t).
*) the parameters in the call to iconv ALL need to be pointers (and no var)

Of course these changes could be rolled into a separate lib but it would be better if someone could adjust synaicnv.pas.
(This was just testing a bit to see if I could get it working.)

uses Windows; // , synachar, synaicnv;

type
  iconv_t = Pointer;
  argptr = iconv_t;

const
  LIBICONV_SO = 'iconv.dll';

type
  Ticonv_version = function(): integer; cdecl;
  Ticonv_open = function(tocode: PAnsiChar; fromcode: PAnsiChar): iconv_t; cdecl;
  Ticonv = function(cd: iconv_t; inbuf: PPAnsiChar; inbytesleft: psize_t;
    outbuf: PPAnsiChar; outbytesleft: psize_t): size_t; cdecl;
  Ticonv_close = function(cd: iconv_t): integer; cdecl;
  Ticonvctl = function(cd: iconv_t; request: integer; argument: argptr): integer; cdecl;

var
  _iconv_version: ^integer;
  _iconv_open: Ticonv_open = nil;
  _iconv: Ticonv = nil;
  _iconv_close: Ticonv_close = nil;
  _iconvctl: Ticonvctl = nil;

procedure _libiconv_test;
var
  hLib: Windows.THandle;
  cd: iconv_t;
  outbuf, inbuf: ansistring;
  ib, ob: Pointer;
  ix, ox: size_t;
  rs: size_t;
begin
  hLib := Windows.LoadLibrary(LIBICONV_SO);
  if (hLib = 0) then exit;
  try
    _iconv_version := GetProcAddress(hLib, '_libiconv_version');
    _iconv_open := GetProcAddress(hLib, 'libiconv_open');
    _iconv := GetProcAddress(hLib, 'libiconv');
    _iconv_close := GetProcAddress(hLib, 'libiconv_close');
    _iconvctl := GetProcAddress(hLib, 'libiconvctl');

    if not assigned(_iconv_version) then exit; // 1.17 = version > 1.0
    writeln('Version: ', _iconv_version^ shr 8, '.', _iconv_version^ and $FF);

    cd := _iconv_open(PAnsiChar('UTF-8'), PAnsiChar('WINDOWS-1250'));

    ox := 0;
    rs := _iconv(cd, nil, nil, nil, @ox);
    if rs = size_t(-1) then exit;

    inbuf := 'Test';
    setlength(outbuf, Length(inbuf) * 4);
    ib := PAnsiChar(inbuf);
    ob := PAnsiChar(outbuf);
    ix := Length(inbuf);
    ox := Length(outbuf);
    rs := _iconv(cd, @ib, @ix, @ob, @ox); // all @ pointers
    _iconv_close(cd);

    writeln('Result : ', rs, ' uint ', integer(rs));
    writeln('Character to go in inbuf : ', ix, ' uint ', integer(ix));
    writeln('Character extra in outbuf : ', ox, ' uint ', integer(ox));

    if rs = size_t(-1) then exit;

    writeln('stripping extra chars');
    setlength(outbuf, Cardinal(Length(outbuf)) - ox);

    writeln('---------');
    writeln(inbuf);
    writeln(outbuf);

  finally
      Windows.FreeLibrary(hLib);
  end;
end;

begin

  _libiconv_test;

  // CharsetConversion('Test', CP1250, UTF_8);
  // cd := SynaIconvOpen('UTF-8', 'WINDOWS-1250');
  // rs := SynaIconv(cd, 'Test', Outstr);
  // SynaIconvClose(cd);
  // writeln(OutStr);

  writeln('Press enter');
  readln;

end.

Grtz,
Rik
_______________________________________________
synalist-public mailing list
synalist-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synalist-public

Reply via email to