When upgrading legacy Uniface applications to version 10.4, developers often face a challenge that lies outside the 4GL environment: the 3GL C/C++ interface. Many functions that were standard for decades have been marked as obsolete or removed entirely.
This guide explains what changed in the u3gl.lib interface and how to adapt your C/C++ code for Uniface 10.4.
What changed in the 3GL Interface?
In older versions of Uniface, the 3GL API (h3gl.h) required manual data type conversions and specific memory handling wrappers. With Uniface 10's modernized architecture, the C-API has been streamlined.
The key takeaway: The API is now more standard. It often accepts standard C types directly, rendering many helper functions redundant.
The List of Obsolete Functions
The following functions are obsolete and must be removed or replaced in your C/C++ source code:
Data Conversion (Now Redundant):
-
UCHAR2UF,UUF2CHAR(String conversion) -
UUF2FLT,UFLT2UF(Floating point conversion) -
USTRINGCNV,USTRDUP
Memory Management:
-
UCALLOC,UMALLOC,UREALLOC,UFREE -
USYSALLOC,USYSFREE
Legacy IPC (DDE):
-
UADVISE,UUNADVISE -
UDDESTARTCONV,UDDESTOPCONV -
UCLIENT,USNDMSG
Variable & Field Access:
-
UGETGVR,UPUTGVR(Old Global Variable Register access) -
UGET3GL,UPGET
Migration Strategies by Category
1. String & Data Conversion (UCHAR2UF)
The Change: Modern Uniface API functions in h3gl.h have been updated to accept standard C-strings (char* or const char*) directly. The internal "Uniface format" conversion is no longer exposed or necessary for standard operations.
Migration Action:
- Identify calls to
UCHAR2UForUUF2CHAR. - Remove them. Pass your C-string pointers directly to the modern Uniface API functions (e.g.,
uputparameter,uputglobal).
2. Memory Management (UCALLOC)
The Change: Uniface no longer requires you to use its specific wrappers for memory allocation within your own 3GL logic.
Migration Action:
- Replace
UMALLOC/UCALLOCwith standard Cmallocorcalloc. - Replace
UFREEwith standardfree.
Note: When passing data back to Uniface (e.g., returning a string), ensure you follow the current API documentation regarding buffer ownership. Usually, you write into a buffer provided by Uniface.
3. Global Variables (UGETGVR)
The Change: The concept of accessing "Register" variables specifically via these old functions is deprecated.
Migration Action:
- Switch to the modern
u_get_global/u_put_global(or equivalenth3gl.hfunctions depending on your exact patch level). These functions allow direct access to Uniface$$variables by name without the overhead of the old register logic.
4. DDE and Legacy IPC
The Change: Dynamic Data Exchange (DDE) is an obsolete Windows technology and support has been dropped.
Migration Action:
- These functions have no direct replacement. You must re-architect the integration.
- Use Web Services (REST/SOAP) or COM/.NET Bridge to communicate with external applications.
Code Comparison: Old vs. New
Here is a conceptual example of how your C code might change when writing a string to a Uniface parameter.
❌ Old C Code (Obsolete):
#include "h3gl.h"
void my_c_function() {
char* c_string = "Hello Uniface";
char* uf_string;
// Step 1: Allocate Uniface memory
uf_string = UCALLOC(100);
// Step 2: Convert C string to Uniface format
UCHAR2UF(c_string, uf_string);
// Step 3: Push to Uniface
uputparameter("P1", uf_string);
// Step 4: Cleanup
UFREE(uf_string);
}
✅ New C Code (Uniface 10.4):
#include "h3gl.h"
void my_c_function() {
char* c_string = "Hello Uniface";
// Direct usage!
// The API now handles the internal conversion or accepts the char* directly.
uputparameter("P1", c_string);
}
Conclusion
Cleaning up obsolete 3GL functions is a critical step in stabilizing your Uniface 10.4 migration. By removing redundant conversion logic and switching to standard C memory management, you not only fix compilation errors but also simplify your codebase.
Key Step: Always recompile your C-Modules with the latest h3gl.h provided in the Uniface 10.4 \common\include directory to catch these signatures early.
Top comments (0)