Search code examples
c++cvisual-c++externdllexport

VisualC++ referencing C functions from C++


I am trying to use a ONCRCP-Windows port from a C++ application but I have some problem referencing function within the library. In the library there is a C file which contains the following C function definition:

//xdr_stdi.c
….
void
xdrstdio_create(xdrs, file, op)
    register XDR *xdrs;
    FILE *file;
    enum xdr_op op;
{

    xdrs->x_op = op;
    xdrs->x_ops = &xdrstdio_ops;
    xdrs->x_private = (caddr_t)file;
    xdrs->x_handy = 0;
    xdrs->x_base = 0;
}

A declaration of the same function is present in a header file as follow:

// xdr.h
DllExport void   xdrstdio_create(); /* XDR using stdio library */

If I call this function from a main.c file this works correctly but If I call this from a main.cpp it complains saying:

“error C2660: 'xdrstdio_create': function does not take 3 arguments”

This actually makes sense to me and I am honestly surprised that in C this does not complain… I however tried to include the header file wrapping the #include in an extern C{ #include... } but this did not help. Strangely enough replacing the definition in the header by

DllExport void   xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op);

Makes the library do not compile with error error

C2143: syntax error: missing ')' before '*'

I did not spend time tracking this second issue down... i would rather understand why the first case does work fine in C but not in C++


Solution

  • Oh dear. You have hit one of the subtle differences between C and C++.

    In C++

    void   xdrstdio_create();
    

    declares a function taking zero arguments. In C, it declares a function but you haven't told the compiler how many arguments it takes! It is up to the programmer to pass the right number of arguments of the right type - and if you get it wrong, ... good luck!

    This is an ancient style of function declaration which predates the first C standard (nearly 30 years ago now), and is only maintained for backwards compatibility.

    In C++, you have to declare the function as:

    DllImport void   xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op);
    

    ... which means you need to have a definition of the typedefs XDR and FILE (the latter will be in <stdio.h> - don't know where you will find XDR.

    A better solution might be to find a library which uses a C less than 25 years old (there are very unlikely to be any platforms which have a C++ compiler, but do not have at least a C89 compiler.)