我想将模板函数实例的指针传递给C函数作为回调。显然不可能在extern "C"
中声明模板。
是否保证C ++对非成员函数使用与C相同的调用约定?在extern "C"
中声明一个函数是否有任何其他影响,除了它可以防止不兼容的名称修改?
答案 0 :(得分:5)
直接为C库导出C ++方法或模板函数是个坏主意。如果我有一个C ++程序,那么我通常将C绑定放入其单独的.cpp + .h文件对中,并使用和extern "C"
块包围头文件,并且我在那里只使用C兼容的函数声明。在随附的.cpp文件中,您实现了这些函数,因为它的.cpp文件可以在绑定函数的实际实现中访问C ++特性(模板,类,...),即使它们的签名是C兼容的,使用C友好类型。
在这种情况下,您应该将C绑定函数放入此绑定器.cpp + .h文件中,并且从该函数的实现中,您可以轻松地调用指定模板函数的实例。
简单愚蠢的例子:
<强> 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)
{
// Since the implementation is in a .cpp file here we can do C++ish things.
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);
}
这适用于所有平台而没有任何问题,C / C ++之间的切割明确地分成了自己的文件。
答案 1 :(得分:3)
没有。它不能保证它使用相同的调用约定。您可以使用调用约定修饰符,如_stdcall
,cdecl
,pascal
等。因此,您必须确保双方都知道相同的调用约定。
一种方法是检测受损的名称并为C函数定义适当的原型。
考虑改变设计;既然你无法从C中的模板中受益,你可以定义一个简单的C ++函数(定义为extern“C”)来调用模板化函数。