One of the common issues that always comes up with programming languages is how to mix code written in one language with code written in another.

For example, suppose that you're writing C++ code and wish to call C functions. A common case of this would be to access C functions that manipulate C-style strings, for example strcmp() or strlen(). So as a first try, we might say:

        extern size_t strlen(const char*);

and then use the function. This will work, at least at compile time, but will probably give a link error about an unresolved symbol.

The reason for the link error is that a typical C++ compiler will modify the name of a function or object ("mangle" it), for example to include information about the types of the arguments. As an example, a common scheme for mangling the function name strlen(const char*) would result in:

        strlen__FPCc

There are two purposes for this mangling. One is to support function overloading. For example, the following two functions cannot both be called "f" in the object file symbol table:

        int f(int);

        int f(double);

But suppose that overloading was not an issue, and in one compilation unit we have:

        extern void f(double);

and we use this function, and its name in the object file is just "f". And suppose that in another compilation unit the definition is found, as:

        void f(char*) {}

This will silently do the wrong thing -- a double will be passed to a function requiring a char*. Mangling the names of functions eliminates this problem, because a linker error will instead be triggered. This technique goes by the name "type safe linkage".

So to be able to call C functions, we need to disable name mangling. The way of doing this is to say:

        extern "C" size_t strlen(const char*);

or:

        extern "C" {
                size_t strlen(const char*);
                int strcmp(const char*, const char*);
        }

This usage is commonly seen in header files that are used both by C and C++ programs. The extern "C" declarations are conditional based on whether C++ is being compiled instead of C.

Because name mangling is disabled with a declaration of this type, usage like:

        extern "C" {
                int f(int);
                int f(double);
        }

is illegal (because both functions would have the name "f").

Note that extern "C" declarations do not specify the details of what must be done to allow C++ and C code to be mixed. Name mangling is commonly part of the problem to be solved, but only part.

There are other issues with mixing languages that are beyond the scope of this presentation. The whole area of calling conventions, such as the order of argument passing, is a tricky one. For example, if every C++ compiler used the same mangling scheme for names, this would not necessarily result in object code that could be mixed and matched.

Our Services

Back to Home Page

posted on 2005-08-26 23:47  dayouluo(.Net学生)  阅读(358)  评论(0编辑  收藏  举报