Realization of Dynamic Structure Mechanism with C

In large-scale C projects, there is a problem of compiling consistency between modules and modules. Because C is a static language, the structure members are solidified into address offsets after compilation. When the structure definition is changed, it is necessary to ensure that the relevant modules are fully compiled. , otherwise the process stack will be destroyed and the program cannot actively discover it.

InterBankPlus transaction management has carefully designed the dynamic structure DS mechanism to solve the problem of full compilation, and has done a lot of encapsulation of details to make the use as convenient as possible.

The caller module first DS_NEW a dynamic structure DS, DS_ADD inputs the variable, variable type, value, and then calls the callee module entry function, the callee module DS_GET out the variable from the dynamic structure, DS_SET returns to the dynamic structure after processing, and returns to the caller module, the caller module DS_GET output variables, and finally the DS_DELETE dynamic structure.

It is still recommended to use static structures inside the module, because the internals are generally compiled consistently.

Through the dynamic structure DS mechanism, data can be safely transmitted between modules, and at most, the program can actively discover and report errors, and will not passively cause process exceptions.

Small technologies solve big problems.

#include "ibtm_in.h"

struct DS_infunc
{
	char	ch ;
	short	s ;
	int	i ;
	long	l ;
	float	f ;
	double	d ;
	char	buf[ 64 + 1 ] ;
} ;

int test_DS_infunc( DS *ds )
{
	struct DS_infunc	infunc ;
	
	DS_TRY(ds)
	{
		DS_GET( ds , char , char_field , & (infunc.ch) )
		DS_GET( ds , short , short_field , & (infunc.s) )
		DS_GET( ds , int , int_field , & (infunc.i) )
		DS_GET( ds , long , long_field , & (infunc.l) )
		DS_GET( ds , float , float_field , & (infunc.f) )
		DS_GET( ds , double , double_field , & (infunc.d) )
		DS_GET( ds , char* , string_field , infunc.buf , sizeof(infunc.buf) )
	}
	DS_CATCH(ds)
	{
		printf( "DS_GET failed , LINE[%d] FIELD_NAME[%s] ERROR[%d]\n" , DSGetLastSourceLine(ds) , DSGetFieldName(ds) , DSGetLastError(ds) );
		return -1;
	}
	
	printf( "--- infunc ---\n" );
	printf( "infunc.ch [%c]\n" , infunc.ch );
	printf( "infunc.s  [%hd]\n" , infunc.s );
	printf( "infunc.i  [%d]\n" , infunc.i );
	printf( "infunc.l  [%ld]\n" , infunc.l );
	printf( "infunc.f  [%f]\n" , infunc.f );
	printf( "infunc.d  [%lf]\n" , infunc.d );
	printf( "infunc.buf[%s]\n" , infunc.buf );
	
	DS_TRY(ds)
	{
		DS_SET( ds , char , char_field , 'Z' )
		DS_SET( ds , short , short_field , 9 )
		DS_SET( ds , int , int_field , 87 )
		DS_SET( ds , long , long_field , 654321 )
		DS_SET( ds , float , float_field , 9.8 )
		DS_SET( ds , double , double_field , 7654.3210 )
		DS_SET( ds , char* , string_field , "world" )
	}
	DS_CATCH(ds)
	{
		printf( "DS_SET failed , LINE[%d] FIELD_NAME[%s] ERROR[%d]\n" , DSGetLastSourceLine(ds) , DSGetFieldName(ds) , DSGetLastError(ds) );
		return -1;
	}
	
	return 0;
}

struct DS_caller
{
	char	ch ;
	short	s ;
	int	i ;
	long	l ;
	float	f ;
	double	d ;
	char	buf[ 64 + 1 ] ;
} ;

int test_DS_caller()
{
	struct DS_caller	caller ;
	DS			*ds = DS_NEW( "struct_name" ) ;
	
	if( ds == NULL )
	{
		printf( "DS_NEW failed , errno[%d]\n" , errno );
		return -1;
	}
	
	memset( & caller , 0x00 , sizeof(struct DS_caller) );
	caller.ch = 'A' ;
	caller.s = 1 ;
	caller.i = 23 ;
	caller.l = 456789 ;
	caller.f = 1.2 ;
	caller.d = 3456.7890 ;
	strcpy( caller.buf , "hello" );
	
	DS_TRY(ds)
	{
		DS_ADD( ds , char , char_field , caller.ch )
		DS_ADD( ds , short , short_field , caller.s )
		DS_ADD( ds , int , int_field , caller.i )
		DS_ADD( ds , long , long_field , caller.l )
		DS_ADD( ds , float , float_field , caller.f )
		DS_ADD( ds , double , double_field , caller.d )
		DS_ADD( ds , char* , string_field , caller.buf )
	}
	DS_CATCH(ds)
	{
		printf( "DS_ADD failed , LINE[%d] FIELD_NAME[%s] ERROR[%d]\n" , DSGetLastSourceLine(ds) , DSGetFieldName(ds) , DSGetLastError(ds) );
		DS_DELETE( ds )
		return -1;
	}
	
	test_DS_infunc( ds );
	
	memset( & caller , 0x00 , sizeof(struct DS_caller) );
	
	DS_TRY(ds)
	{
		DS_GET( ds , char , char_field , & (caller.ch) )
		DS_GET( ds , short , short_field , & (caller.s) )
		DS_GET( ds , int , int_field , & (caller.i) )
		DS_GET( ds , long , long_field , & (caller.l) )
		DS_GET( ds , float , float_field , & (caller.f) )
		DS_GET( ds , double , double_field , & (caller.d) )
		DS_GET( ds , char* , string_field , caller.buf , sizeof(caller.buf) )
	}
	DS_CATCH(ds)
	{
		printf( "DS_GET failed , LINE[%d] FIELD_NAME[%s] ERROR[%d]\n" , DSGetLastSourceLine(ds) , DSGetFieldName(ds) , DSGetLastError(ds) );
		DS_DELETE( ds )
		return -1;
	}
	
	printf( "--- caller ---\n" );
	printf( "caller.ch [%c]\n" , caller.ch );
	printf( "caller.s  [%hd]\n" , caller.s );
	printf( "caller.i  [%d]\n" , caller.i );
	printf( "caller.l  [%ld]\n" , caller.l );
	printf( "caller.f  [%f]\n" , caller.f );
	printf( "caller.d  [%lf]\n" , caller.d );
	printf( "caller.buf[%s]\n" , caller.buf );
	
	DS_DELETE( ds )
	
	return 0;
}

int main()
{
	return -test_DS_caller();
}

 

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324117403&siteId=291194637