Re: C code in C++ and used inside class
On Aug 4, 9:49 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
cognacc@ wrote:
Im trying to use some C code inside a C++ class, this class is used
in another C++ class ofcourse, or will be.
The C++ class will contain a data structure
from the C code amongst others.
But in the C code header file where the datatype is defined, there are
also some global variables defined.
That's A VERY BAD IDEA(tm). Variables should never be *defined* in hea=
ders.
I mean declared sorry. if in header:
int Ggloabalvar; // this is a declaration right
s_57_defs.h this is the file with a few globals vars
and also a datatype conversion, works fine compiled as C.
---------------------------------------------------------------------------=
--
#ifndef _S_57_DEFS_H
#define _S_57_DEFS_H
/*
* File: s_57_defs.h
* Author: run
*
* Created on March 10, 2009, 3:07 PM
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/queue.h>
typedef char octet;
typedef char tag[5]; //! \todo ? check this typedef, see page 146 k&r
// Leader is 24 octets (bytes long) both DDR an DR leader (S-57)
#define LEADER_SIZE 24
// Fieldtag size ie VRID, is 4 octets long, specified int S-57
#define FIELD_TAG_SIZE 4
// SHOULD Probably read this and check, but not now
// field RP 09
#define DDR_FIELD_CONTROL_LENGTH 9
// See iso8211 table 1 delimiter and their uses
// Unit terminator : printable '&' : Terminates a unit in a field
#define UT 0x1F // dec: 31 oct: \037
// Field terminator : printable ';' : Terminates a complete field(ex:
VRID)
#define FT 0x1E // dec: 30 oct: \036
// This could be defined for each field (vrid, frid etc.)
#define STD_SIZE_LEN 220
struct GNAME {int len; char val[10];};
//
==========================
==========================
==========================
====
// global variables for conversion between octets to datatypes
// bXY : X is signednes Y is width in octets
unsigned char S57TYPE_b11; // UNSIGNED ONE OCTET CHAR
signed char S57TYPE_b21; // SIGNED ONE OCTET UNSIGNED CHAR
unsigned short S57TYPE_b12; // UNSIGNED TWO OCTET UNSIGNED CHAR
signed short S57TYPE_b22; // SIGNED TWO OCTET SIGNED CHAR
unsigned long S57TYPE_b14; //
signed long S57TYPE_b24; //
unsigned char S57TYPE_B5[5];
unsigned char S57TYPE_B8[8];
unsigned char S57TYPE_B[20]; // any large enough number
// DUMMY just to shut compiler up
char S57TYPE_A[200];
char S57TYPEA_UL[200]; // ascii unspecified length
char S57TYPEA_L8[8]; // which lengths
char S57TYPE_I[200]; // type i of generic legnth, real
length seen at data read time
double S57TYPE_R; // \note correct S57TYPE long ?
- think its incorrect!?
int LENGTH_TYPESIZE; // length to send as
parameter to function
// User defined define a head of a new queue
// Should define a tailqueue , a new call to getRecordSet() will reuse
same queue
TAILQ_HEAD(tailhead, DR_Data) dr_head;
typedef struct DR_Data // DR_Data is tag
{
char fieldtagname[5]; // the tagname, like VRID FOID DSSI, can be
used to look at the S57TYPE (if NAME = cast S57TYPE)
//BOOL is_toplevel; // is a toplevel field (ex: VRID)
int is_toplevel;
// record numbers used for debugging data structures
int dr_rec_nr; // total records ie FIELD numbers
int dr_toplevel_nr; // top level FIELDS (VRID, FOID, DSID, DSSI, ..)
number of toplevel fields, called a "RECORD BLOCK"
int dr_repeat_nr; // repeating fields number, same fields repeating
count
// int dr_different_fields // total fields exclusive repeating
fields (counted once)
//-----------------
void *field_ptr; // void pointer to a field a HUGE case for
casting to field S57TYPE (or look out for aut5o generating)
struct DR_Data *next_data; // DR_Data is tag
// LIST struct list_head somename see man queue (LIST*)
TAILQ_ENTRY(DR_Data) dr_data_list;
}DR_Data; // DR_Data i typedef
//typedef _dr_data DR_Data;
DR_Data *dr_data_ptr, *dr_data_pnext, *dr_data_pprev;
struct tailhead *pos_data, *q_data, *dr_head_ptr;
void usage(char **arg);
// DR_Data *
int readRecordSet(char * s57_filename);
void queue_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _S_57_DEFS_H */
-----------------------------------------------------------------------
Is there a way to avoid multiple inclusion error, without changing the
C code?
You could try creating another header with double inclusion guards and
include that C header there, but it looks like you'd be better off
rewriting the C stuff to make it proper.
Double inclusion guards? how?
Here is a C++ file using the data structure:
DR_Data *genericDRData; is the type from C i need to use in my class
---
#ifndef CHARTINFO_H
#define CHARTINFO_H
#include <string>
extern "C"
{
#include <stdlib.h>
#include <assert.h>
#include "../../decode_seacharts/s_57_defs.h" // <---- header with
datatype and global var, we only use the type(s)
}
// inner struct / class
// latitude and longtiude coordinates
struct LatLon
{
signed long lat; // Latitude
signed long lon; // Longtitude
};
struct XYPos
{
int lat; // Latitude
int lon; // Longtitude
char * unit; // m or km // define domains ?
};
class ChartInfo
{
public:
ChartInfo();
void loadRecordSet(char *filename);
long long getLNAME_id(); // RCNM '+' RCID
long long getNAME_id();
signed long getLattitude();
signed long getLongtitude();
int translateLatLon_to_meters(struct LatLon ll);
int translateLatLon_to_kilometers(struct LatLon ll);
// test function traverse all dr_data
void traverseAllDRData();
private: // private functions
long long getRecordSet_key();
double convertLatLon_to_degree(signed long lon_or_lat);
//=========================
===============
// private variables and data
DR_Data *genericDRData; // <----- a pointer to use with tailq
maybe readRecordSet should return that
//..
// RCNM b11 + RCID b14 => name_key_identifier
long long name_record_identifier;
// lname AGEN + FIDN + FIDS -> lname_key_identifier
long long lname_record_identifier;
};
#endif // CHARTINFO_H
---
Please tell if i post to much code (or to little, i have cleaned it up
some,
for easier reading and removed a few lines i was trying out).
I can Change the C file but i want to avoid that, in C declaring
common variables
in a header is pretty normal i think.
So maybe what im trying to do is write a small wrapper, but i never
done that before.
Mic