Skip to content

Session with Marek #174

Description

@FiveTechSoft

Issue: Lessons learned connecting FiveTechSoft Harbour + HMG rddads to OpenADS server

Summary

Successfully connected a FiveTechSoft Harbour 3.2 + HMG 3.4.4 (32-bit, MinGW) client to OpenADS 1.8.83 remote server. Documenting issues encountered and fixes applied to help other users.

Environment

  • Server: OpenADS 1.8.83-1-gd89f323 (openads_serverd.exe x64)
  • Client: FiveTechSoft Harbour 3.2.0dev (r2410251209) + HMG 3.4.4.ssl3 (built from source)
  • ACE DLL: ace32.dll built from OpenADS source via CMake (msvc-x86-static preset with /MT)
  • Import library: Generated with dlltool --no-leading-underscore from openace32.dll

Issues encountered and fixes

1. Import library: ordinal vs name-based exports

Problem: The OpenADS openace32.dll exports both ordinal ([41] AdsConnect) and decorated name (_AdsConnect@8) exports. The initial import library was generated using ordinal matching, which worked for x64 but caused crashes on i686 (32-bit).

Fix: Generate the import library using name-based exports with --no-leading-underscore:

dlltool -d ace32.def -l libace32.a --no-leading-underscore

This ensures PE import names (_AdsConnect@8) match exactly what the DLL exports, avoiding ordinal mismatches.

2. Missing VC++ runtime (static CRT fix)

Problem: The MSVC-built ace32.dll required VCRUNTIME140.dll. On machines without the VC++ redistributable installed, the client crashed silently.

Fix: Rebuilt ace32.dll with static CRT using the msvc-x86-static CMake preset (/MT flags). The resulting DLL only depends on KERNEL32.dll and WS2_32.dll.

3. URI must include the data directory path

Problem: Using tcp://127.0.0.1:16262/ (empty path) in AdsConnect60() caused "Connect: path outside data directory" error.

Root cause: In session.cpp, resolve_under_root() returns std::nullopt for empty client paths (path.cpp:105). The server requires a non-empty path to resolve against its --data roots.

Fix: Include the data directory in the URI:

tcp://127.0.0.1:16262/D:/path/to/data

This matches the pattern used in unit tests (tests/unit/) and the E2E test (tests/e2e/README.md).

4. CDX index file must exist before remote USE

Problem: USE CCOLONIA.DBF ALIAS CCOL NEW EXCLUSIVE VIA "ADSCDX" hung indefinitely (never returned) when the .cdx file did not exist.

Root cause: Server error 5103 (OpenIndex: CCOLONIA.cdx) — the ADSCDX RDD automatically tries to open a matching CDX file. If it doesn't exist, the server returns an error but the client-side RDD doesn't handle it properly and hangs.

Fix: Create the CDX index file locally before connecting remotely:

USE CCOLONIA ALIAS CCOL NEW EXCLUSIVE VIA "DBFCDX"
INDEX ON CCOL->COLONIA TAG COLONIA
INDEX ON CCOL->NOMBRE TAG NOMBRE
CCOL->(DbCloseArea())

5. ? console output in GUI mode

Problem: Using ? (console output) inside functions called from a -gui build caused HMG ErrorSys to catch an error and show a "Program Error" dialog, even though the ? calls were harmless.

Fix: Replace all ? console output with file-based tracing (MemoWrit) for GUI applications. Use append-on-write pattern:

FUNCTION _tlog( cFile, cMsg )
   LOCAL cOld := ""
   IF File( cFile )
      cOld := MemoRead( cFile )
   ENDIF
   MemoWrit( cFile, cOld + Time() + " " + cMsg + Chr(13)+Chr(10) )
RETURN

6. DBF file must be valid before remote open

Problem: The initial CCOLONIA.DBF was created with incorrect parameters (empty field descriptors, RecSize=0). The server would accept the USE but the client would hang.

Fix: Ensure the DBF has proper structure with valid field definitions before connecting remotely.

Key patterns from unit tests

The OpenADS unit tests (tests/unit/) reveal the correct API usage patterns:

Aspect Pattern
Local connect AdsConnect60(dir_path, ADS_LOCAL_SERVER, nullptr, nullptr, 0, &hConn)
Remote connect AdsConnect60("tcp://127.0.0.1:<port>/<data-path>", ADS_REMOTE_SERVER, ...)
Open table AdsOpenTable(hConn, "filename.dbf", ...) — bare filename only
Data path Goes in the connection URI, not in the table name

Suggested improvements

  1. Better error reporting for ADS 5103: When a CDX file is missing, the client-side RDD should return an error instead of hanging.
  2. Empty URI path handling: Consider defaulting to the server's --data root when the client sends an empty path in the URI (with a deprecation warning).
  3. ACE DLL version string: The built-in AdsVersion() returns "1.8a" which is the DLL header version, not the server version. Consider including the OpenADS git version.

Files modified

  • colonias.prg — Main program with file-based tracing
  • colonias_common.prg — Remote connection flow with verbose trace logging
  • Import library: libace32.a generated with dlltool --no-leading-underscore

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions