如何从 C 调用模板化的 C++ 自由函数?

问题描述 投票:0回答:2

我想将函数模板实例的指针传递给 C 函数作为回调。显然不可能将模板声明为

extern "C"

是否保证 C++ 对非成员函数使用与 C 相同的调用约定?除了防止不兼容的名称修改之外,在

extern "C"
中声明函数还有其他效果吗?

c++ c calling-convention function-templates extern-c
2个回答
6
投票

直接为 C 库导出 C++ 方法或模板函数不是一个好主意。在 C++ 代码库中,我通常将 C 绑定放入专用的 .cpp + .h 文件对中 - 头文件必须使用

extern "C"
块和 C 兼容函数声明。在随附的 .cpp 文件中,您可以实现 C 函数,并且由于它是 .cpp 文件,因此您可以访问 C++ 功能(模板、类、C++ 函数等)。

示例:

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
...

随便吧。c:

#include "CBindings.h"
#include <stdio.h>

void my_c_func(void)
{
    int i = int_from_string("5");
    printf("%d\n", i);
}

3
投票

不。不保证它使用相同的调用约定。您可以使用调用约定修饰符,如

_stdcall
cdecl
pascal
等。因此,您必须确保双方都知道相同的调用约定。

一种方法是检测损坏的名称并为 C 函数定义正确的原型。

考虑改变设计;因为无论如何您都无法从 C 中的模板中受益,所以您可以定义一个简单的 C++ 函数(定义为 extern“C”)来调用模板化函数。

© www.soinside.com 2019 - 2024. All rights reserved.