How to split this into header and source files? - c

I have some C code I'd like to split into a header file and a source file:
#ifndef BENCHMARK_H
#define BENCHMARK_H
#ifdef WIN32
#include <windows.h>
double get_time()
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart/(double)f.QuadPart;
}
#else
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#endif
#endif
What would be the proper format of the resulting benchmark.h and benchmark.c?
I know the header file should contain function declarations, while the source file should be where the actual function definitions reside. Would this following code be correct? Namely, should the #ifdef WIN32 directive be in both files as I have it below? Or should it all be in the .c file?
benchmark.h
#ifndef BENCHMARK_H
#define BENCHMARK_H
#ifdef WIN32
#include <windows.h>
#else
#include <sys/time.h>
#include <sys/resource.h>
#endif
double get_time();
#endif
benchmark.c
#ifdef WIN32
double get_time()
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart/(double)f.QuadPart;
}
#else
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#endif

Together, a header file and a c file form a "code module" (or if you will: an ADT, a class etc).
The header file is always to be regarded as the user interface of your code, where the "user" is the programmer who is going to use your module. It shall never contain any code or variable definitions, period.
While the c file contains the actual implementation, which is of no interest to the user, and should not be of any concern to them. The c file should use private encapsulation and everything that the user need not know should be in that file.
The above is how you design C programs, or any program in any language. This is not subjective, it is not opinion-based, it is the only way. If you are doing your program design differently, you are doing it wrong.
As for your specific program, it should be designed in the following way:
benchmark.h
#ifndef BENCHMARK_H
#define BENCHMARK_H
double get_time (void);
/* documentation about how this function is used should be put here */
#endif
benchmark.c
#include "benchmark.h"
/*** Include files ***/
#ifdef WIN32
#include <windows.h>
#else
#include <sys/time.h>
#include <sys/resource.h>
#endif
/*** Other stuff, for example constants, typedefs, static file scope variables ***/
/*** function definitions ***/
#ifdef WIN32
double get_time (void)
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart/(double)f.QuadPart;
}
#else
double get_time (void)
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#endif
Note that double get_time() means "function that accepts any parameter" in C. That is poor style, use void instead. C and C++ are different in this regard. In C++, func() and func(void) mean the same thing.

I would simplify it to this, the only thing needed in the header file is the function prototype.
benchmark.h
double get_time();
benchmark.c
#ifdef WIN32
#include <windows.h>
#include "benchmark.h"
double get_time()
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart/(double)f.QuadPart;
}
#else
#include <sys/time.h>
#include <sys/resource.h>
#include "benchmark.h"
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#endif

Related

Compile DLL with a static library using gcc (mingw32)

I've a static library let's call it libsecondary.a generated by a external tool, i.e CGO. I want to generate a dynamic library while including "libsecondary.a" as a dependency, I export a function called OnProcessInit() inside libsecondary.h and call it on the DLL_PROCESS_ATTACH event.
I tried to generate the shared library but seems to fail using
x86_64-w64-mingw32 -shared -L. -lsecondary -static-libgcc -static-libstdc++ -static .\dllmain.c
The error output is
dllmain.c:(.text+0x9b): undefined reference to `OnProcessInit', what's going on?
This is the header file libsecondary.h
/* Code generated by cmd/cgo; DO NOT EDIT. */
/* package command-line-arguments */
#line 1 "cgo-builtin-export-prolog"
#include <stddef.h>
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#endif
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef size_t GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
#ifdef _MSC_VER
#include <complex.h>
typedef _Fcomplex GoComplex64;
typedef _Dcomplex GoComplex128;
#else
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
#endif
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern __declspec(dllexport) void OnProcessInit();
#ifdef __cplusplus
}
#endif
And this is dllmain.c
#include <windows.h>
#include <stdio.h>
#include "libsecondary.h"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
printf("It works i guess");
OnProcessInit();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
This is the exported golang function (the one that I compile using go build -buildmode=c-archive)
package main
import "C"
import (
"unsafe"
"syscall"
)
//export OnProcessInit
func OnProcessInit() {
const (
NULL = 0
MB_OK = 0
)
caption := "Hola"
title := "desdegoo"
ret, _, _ := syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW").Call(
uintptr(NULL),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
uintptr(MB_OK))
if ret != 1 {
return
}
return
}
func main() {}
Wow, the answer was the argument position,
x86_64-w64-mingw32 -shared -static-libgcc -static-libstdc++ -static .\dllmain.c .\libsecondary.a
If you type it backwards it won't find references from libsecondary.a, jeez...
Also the above code runs into a deadlock upon getting loaded, because syscall.NewLazyDLL calls LoadLibraryA, and it's locked inside DLL_PROCESS_ATTACH, so the way to go is to CreateThread and run the golang exported function inside the thread :)

error: expected declaration specifiers or '…' before string constant

Does anybody know what is wrong with this piece of code? i can't see to find the issue among the comparable questions.
The code is written in C, and i keep getting this error. I do add -D SET_MIN_TEMP=5 -D Set_MAX_TEMP=30 to the gcc compile line to make sure the ifndefs should be false...
#ifndef CONFIG_H
#define CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#ifndef RUN_AVG_LENGTH
#define RUN_AVG_LENGTH 5
#endif
#ifndef SET_MIN_TEMP
printf("please set SET_MIN_TEMP \n");
#endif
#ifndef SET_MAX_TEMP
printf("please set SET_MAX_TEMP \n");
#endif
typedef uint16_t sensor_id_t;
typedef uint16_t room_id_t;
typedef double sensor_value_t;
typedef time_t sensor_ts_t; // UTC timestamp as returned by time() - notice that the size of time_t is different on 32/64 bit machine
typedef struct {
sensor_id_t id;
sensor_value_t value;
sensor_ts_t ts;
} sensor_data_t;
typedef struct {
sensor_id_t sensor_id;
room_id_t room_id;
double running_avg[5];
sensor_ts_t timestamp;
} sensor_node_t;
#endif // CONFIG_H
You can not use a function call (printf) outside a function. You should take a look at #error if you want to report errors at compilation...
See here

Redefinition of type in c, but guard is included?

I have code that I can't compile on one computer. It works on my PC, but on another it doesn't work. The error is "redefinition of typdef cplx" even though I have guard on every header file and I have guard for every definition of typdef:
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
Why this problems occurs?
Here are two header files. blas.h:
#ifndef BLAS_H
#define BLAS_H
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
//declaration of functions
#endif
and lapack.h:
#ifndef LAPACK_H
#define LAPACK_H
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
//declarations of functions
#endif
The problem is when I include both, lapack.h and blas.h, I get this error?
Your guards protect against the same include file being included twice, but you have two different include files with two different guards, and you define cplx in each one.
You need a separate guard for that type in each include file, like this:
#ifndef CPLX
#define CPLX
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
//declarations of functions
#endif

Discover available clock types at compile time

[Ubuntu 14.04, 3.16.0-34-generic Kernel, GCC 4.8.4, Clang 3.5.0]
I'm writing some elapsed time performance routines for an application I have, and I would like to do it in a cross-platform manner.
I would like to write it in such a way that the right clock type is selected during compile, rather than run-time (which I can do by testing for failures and using fallbacks).
The clock_getres(2) man page states:
On POSIX systems on which these functions are available, the symbol _POSIX_TIMERS is defined in <unistd.h> to a value greater than 0. The symbols _POSIX_MONOTONIC_CLOCK, _POSIX_CPUTIME, _POSIX_THREAD_CPUTIME
indicate that CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID are available. (See also sysconf(3).)
I have included in my code , , and but my conditional compile statements don't recognise the symbol _POSIX_MONOTONIC_CLOCK. It always prints the 'gettimeofday' message. I've tried GCC and Clang but get the same result.
My code below is incomplete (and incorrect) and I would appreciate some assistance on how to do this right.
#include <unistd.h>
#include <features.h>
#include <stdio.h> // printf (otherwise forward declaration warning)
#include <stdlib.h> // NULL
#include <sys/time.h>
long long get_utime(void)
{
struct timeval tv;
if (gettimeofday(&tv, NULL) == -1) return -1LL;
long long t = (long long) tv.tv_usec +
(long long) tv.tv_sec * 1000000LL;
return t;
}
int main() {
union time{
struct timespec tSpec;
long long tLL;
} myT;
#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &myT.tSpec);
printf("CLOCK_MONOTONIC_RAW\n");
#elif _POSIX_MONOTONIC_CLOCK
clock_gettime(CLOCK_MONOTONIC, &myT.tSpec);
printf("CLOCK_MONOTONIC\n");
#else
myT.tLL = get_utime();
printf("gettimeofday\n");
#endif // CLOCK_MONOTONIC_RAW
return 0;
}
I'm not using any configure or auto-configure software.
Also, a comment about the relative speeds of CLOCK_MONOTONIC & CLOCK_MONOTONIC_RAW would be nice. I understand the difference and their limitations.
You aren’t declaring the headers and feature-test macros that the man page says you need. This works:
#define _POSIX_C_SOURCE 200809L // <- This was missing.
#define _XOPEN_SOURCE 700 // <- This is optional.
#include <unistd.h>
#include <stdio.h> // printf (otherwise forward declaration warning)
#include <stdlib.h> // NULL
#include <sys/time.h>
#include <time.h> // <- This was missing.
long long get_utime(void)
{
struct timeval tv;
if (gettimeofday(&tv, NULL) == -1) return -1LL;
long long t = (long long) tv.tv_usec +
(long long) tv.tv_sec * 1000000LL;
return t;
}
int main() {
union time{
struct timespec tSpec;
long long tLL;
} myT;
#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &myT.tSpec);
printf("CLOCK_MONOTONIC_RAW\n");
#elif _POSIX_MONOTONIC_CLOCK
clock_gettime(CLOCK_MONOTONIC, &myT.tSpec);
printf("CLOCK_MONOTONIC\n");
#else
myT.tLL = get_utime();
printf("gettimeofday\n");
#endif // CLOCK_MONOTONIC_RAW
return 0;
}

Getting problem with timing in C in visual studio 2010

I have a function for getting system time. The function is defined as follows.
int getSystemTime(struct timeval tv, void * tz);{
DWORD milliseconds;
milliseconds = timeGetTime();
tv->tv_sec = milliseconds / 1000;
tv->tv_usec = (milliseconds % 1000) * 1000;
return 0;
}
Precisely following are the problems:
1.error: identifier DWORD is undentified .
2.error: identifier timeGetTime() is undefined.
3.error: identifier suseconds_t is undefined.
I tried to include windef.h where DWORD is defined. But the problem is, I got the error like:
1. error: identifier PCONTEXT is undefined.
The header file for time included is time.h. Here the timeval defined is:
#ifndef _WINSOCK_H
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
Could you please tell me what shall I do to make this function run in windows environment?
[EDIT]
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
#ifdef HAVE_MMSYSTEM_H
#include <mmsystem.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
You need to include windows.h at the top of your C file.

Resources