7 Reeds
7 Reeds

Reputation: 2539

c++: g++: extern "C" function definition?

I am having trouble creatiung a C++ library with a extern "C" function interface. I have the following header

#ifndef MYUTILITIES_H_
#define MYUTILITIES_H_

namespace MYUtilities {

    static std::string UpperCase(std::string);

    class MyException: public std::exception {
        public:
            MyException(std::string ss)
                    : s(ss) {
            }
            ~MyException() throw () {
            } // Updated

            std::string s;

            const char* what() const throw () {
                return s.c_str();
            }
    };

} /* namespace ITGUtilities */

/*
 * General utility functions
 */
extern "C" const char * UpperCase(const char *);

#endif /* MYUTILITIES_H_ */

source file

#include "ITGUtilities.h"

namespace ITGUtilities {

    const char * UpperCase(const char * str) {
        std::string tmp = str;
        std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
        return tmp.c_str();
    }

    std::string UpperCase(std::string str) {
        std::string tmp = str;
        std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
        return tmp;
    }

} // namespace ITGUtilities

In the .cpp source file I have tried defining the char *UpperCase(const char *) routine inside and outside of the namespace. In either case nothing that tries to use this library can find a reference for the extern function.

I have seen an example in the MySQL C++ cppcon/driver.h header where the extern definition is in the header but outside the namespace.

extern "C"
{
    CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance();

    /* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */
    CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib);
}

I just don't know what magic I should be using here.

help?

Upvotes: 0

Views: 367

Answers (2)

SergeyA
SergeyA

Reputation: 62563

First of all, do not define extern functions in namespaces, it makes no sense. To check what was the name of generated function in object file, use utility called nm (on *nix). It should tell you of the name was mangled or not.

In your case, I assume the problem is that you have an overload with a different name and C++ linkage. I suggest you name your C-linkage function differently.

Upvotes: 0

Logicrat
Logicrat

Reputation: 4468

Use the curly braces to define your external C function:

extern "C"
{
    UpperCase(const char *);
}

Upvotes: 1

Related Questions