Cross platform lib in 'C'

C

Carnage

I want to provide a common platform agnostic function declaration
which references different implementations for different hardware
platforms.

What is the most type safe way to do this in 'C'?
 
U

user923005

I want to provide a common platform agnostic function declaration
which references different implementations for different hardware
platforms.

What is the most type safe way to do this in 'C'?

I'm not sure if we can really believe in an agnostic function.

At any rate, if you write in ANSI/ISO C, then your code will be
portable.

As to data portability -- it's not.
You will have to use something like netCDF to help you there:
http://www.unidata.ucar.edu/software/netcdf/

And that is only a partial solution (it handles fundamental data types
only).
 
K

Keith Thompson

Carnage said:
I want to provide a common platform agnostic function declaration
which references different implementations for different hardware
platforms.

What is the most type safe way to do this in 'C'?

void func(void) is platform-independent.

I don't think your question can be answered without more information
about what you're trying to do. What function(s) are you trying to
declare, and what are they supposed to do?
 
C

Carnage

void func(void) is platform-independent.

I don't think your question can be answered without more information
about what you're trying to do. What function(s) are you trying to
declare, and what are they supposed to do?

--
Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

eg. I want to supply an interface for some file open functionality but
there are different implementations for each platform my lib supports.

One way would be something like:

//File.h

#if defined(WIN32)
#include "FileWin32.h"
#elif defined(OTHEROS)
#include "FileOtherOs.h
#endif

#define OpenFile _OpenFile

//FileWin32.h

typedef void * FileHandle;
FileHandle _OpenFile(const char * name, const char * access);

//FileWin32.c

FileHandle _OpenFile(const char * name, const char * access)
{
//Do win32 specific fopen etc..
}

...Similar for OtherOS...
===========================


Another alternative which I think might be better is:

//File.h
typedef void * (*FileOpenFunction)(const char * name, const char *
access);
extern FileOpenFunction FileOpen;

//FileWin32.cpp
static void * FileOpenWin32(const char * name, const char * access);

FileOpenFunction FileOpen = FileOpenWin32;

static void * FileOpenWin32(const char * name, const char * access)
{
//Do win32 specific fopen etc..
}


In the second example seems better to me since there is no platform
#if stuff required and no use of macro defines and also no header
required for each platform implementation - eg FileWin32.h is not
required any more.

Any other ideas?
 
C

CBFalconer

Carnage said:
.... snip ...

eg. I want to supply an interface for some file open functionality
but there are different implementations for each platform my lib
supports. One way would be something like:

//File.h

#if defined(WIN32)
#include "FileWin32.h"
#elif defined(OTHEROS)
#include "FileOtherOs.h
#endif

#define OpenFile _OpenFile

//FileWin32.h

typedef void * FileHandle;
FileHandle _OpenFile(const char * name, const char * access);

You don't need any of that nonsense. That's the point of a
standard. Just use fopen. The implementation itself will take
care of mapping things to the appropriate available system
routines.
 
C

Carnage

Carnage wrote:

... snip ...



You don't need any of that nonsense. That's the point of a
standard. Just use fopen. The implementation itself will take
care of mapping things to the appropriate available system
routines.

I only chose fopen as an example to debate methods for building a
cross-platform interface to platform specific implementation. Besides,
what if on a 'certain' platform I didn't want to use fopen but rather
some other custom file interface anyway. Substitute fopen with
ProcessWidget if it helps you.
 
C

CBFalconer

Carnage said:
.... snip ...


I only chose fopen as an example to debate methods for building a
a cross-platform interface to platform specific implementation.
Besides, what if on a 'certain' platform I didn't want to use
fopen but rather some other custom file interface anyway.
Substitute fopen with ProcessWidget if it helps you.

Non-standard routines are off topic here, unless you include the
code for them, written in portable standard C. You have no need to
not use fopen, it is always available on a hosted system.
 
M

Mark F. Haigh

I want to provide a common platform agnostic function declaration
which references different implementations for different hardware
platforms.

What is the most type safe way to do this in 'C'?

The term for what you want to do is "wrapping". To properly wrap
platform-specific APIs, do the following:

1. Understand what you want to do. Ask yourself questions like: "In
an ideal world, how would the rest of my code interface with the
desired functionality?", "What information would the wrapper code need
to successfully accomplish the things it needs to accomplish?", and
"How would I express what I'm trying to do in plain English to a
fellow programmer who is not familiar with the particulars?"

2. Understand the platform-specific APIs on the platforms you care
about. How do they work? Have you written test cases or prototypes
to drive the desired functionality?

3. Sort the implementations into categories. Sometimes this falls
into per-platform, per-OS, per library, etc.

4. Create a seperate file for each category you came up with in step
3. In each file, write different, platform-specific implementations
of the same function.

Using your example, you would have two files: FileOpenWin32.c and
FileOpenOther.c. Both files implement the function FileOpen().

The rest of your code can just call FileOpen() without worrying about
the details of how FileOpen() works. You can call the function the
same exact name on both platforms because it's impossible to have them
both compiled in at once.

Mark F. Haigh
(e-mail address removed)
 
S

Stephen Sprunk

Carnage said:
I want to provide a common platform agnostic function declaration
which references different implementations for different hardware
platforms.

What is the most type safe way to do this in 'C'?

Type safety isn't the concern; it's logistics.

There are two common techniques I've seen. The first is used if the
implementations share very little in common. You create a single header
file, e.g. mylib.h, and a separate source file for each implementation, e.g.
mylib-posix.c, mylib-win32.c, etc. Then, you structure the build (e.g.
Makefile) so that the appropriate file is compiled into an object that's
always named the same, e.g. mylib.o. Then you can just blindly link in that
file later without having to worry about which source file it was compiled
from.

The second is used if the implementations are mostly common but have a few
critical differences. Just create one source file as normal, but break out
the varying sections with #ifdefs, and set up the build environment so that
the correct macro (e.g. POSIX, WIN32, etc.) is defined so that the correct
parts of the code are compiled in.

As long as the API is defined in a portable manner, you can safely put all
sorts of evil non-portable stuff in your private implementation. Of course,
your code will only work on systems you've written implementations for...

S
 
B

Barry

user923005 said:
I'm not sure if we can really believe in an agnostic function.

Of course dyslexic agnostic functions waffle on whether to
mallocate space for dog.
 
C

Carnage

Type safety isn't the concern; it's logistics.

There are two common techniques I've seen. The first is used if the
implementations share very little in common. You create a single header
file, e.g. mylib.h, and a separate source file for each implementation, e.g.
mylib-posix.c, mylib-win32.c, etc. Then, you structure the build (e.g.
Makefile) so that the appropriate file is compiled into an object that's
always named the same, e.g. mylib.o. Then you can just blindly link in that
file later without having to worry about which source file it was compiled
from.

The second is used if the implementations are mostly common but have a few
critical differences. Just create one source file as normal, but break out
the varying sections with #ifdefs, and set up the build environment so that
the correct macro (e.g. POSIX, WIN32, etc.) is defined so that the correct
parts of the code are compiled in.

As long as the API is defined in a portable manner, you can safely put all
sorts of evil non-portable stuff in your private implementation. Of course,
your code will only work on systems you've written implementations for...

S

Thanks - that helped me think about my problem more clearly. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top