It's a bad idea to export C++ methods or template functions directly for a C library. In a C++ codebase I usually put the C bindings into a dedicated .cpp + .h file pair - the header file has to use an extern "C"
block and C compatible function declarations. In the accompanying .cpp file you implement the C functions and since it's a .cpp file you can access C++ features (templates, classes, C++ functions, ...).
Example:
CBindings.h:
// This is the header used by both C++ and C
#ifdef __cplusplus
extern "C" {
#endif
// C compatible function declarations with C-friendly types.
int int_from_string(const char* s);
#ifdef __cplusplus
}
#endif
CBindings.cpp:
#include "CBindings.h"
#include "WhateverCPPHeader.h"
int int_from_string(const char* s)
{
// We can use C++ features because the implementation is in a .cpp file.
return FromString<int>(s);
}
WhateverCPPHeader.h:
// Somewhere in your C++ header files:
template <typename T>
T FromString(const std::string& s);
...
// Template specializations of FromString for several T types
...
Whatever.c:
#include "CBindings.h"
#include <stdio.h>
void my_c_func(void)
{
int i = int_from_string("5");
printf("%d\n", i);
}
x64
there is only one calling convention. It differs between Unix-like and Microsoft, but within one OS it's just one calling convention. – Gardie