c++;如果c函数确实存在,则调用它 我有一些C++代码,自动生成来包装一些C代码。< /P>

c++;如果c函数确实存在,则调用它 我有一些C++代码,自动生成来包装一些C代码。< /P>,c++,sfinae,C++,Sfinae,C代码有一个可预测的结构,但有/没有特定的功能除外 因为C++代码是从没有这个信息的描述中派生出来的。我想使用模板处理器来决定是否可以调用此函数 小例子: struct SomeStruct{ int indicatorMember; }; extern "C" void someFun(struct SomeStruct* somePointer){ } void someCPPcode(){ SomeStruct s; // do something someMech

C代码有一个可预测的结构,但有/没有特定的功能除外

因为C++代码是从没有这个信息的描述中派生出来的。我想使用模板处理器来决定是否可以调用此函数

小例子:

struct SomeStruct{
  int indicatorMember;
};
extern "C" void someFun(struct SomeStruct* somePointer){
}



void someCPPcode(){
  SomeStruct s;
  // do something

  someMechanismToCall_someFunIfExists(&s);

  // do something other
}
somemechanismCall\u somefunif exists
必须是什么样子,以便在存在
someFun
的情况下编译/运行someCpCode

这可能吗

如果某个构件是结构的一部分,也可以确定该功能是否存在。
因此,如果指示器成员确实存在,则该函数也存在。

关于是否存在具有外部链接的某个符号的定义的问题本质上是一个只能在链接过程中才能回答的问题。在编译单个C++源文件时,编译器没有办法知道是否有其他外部函数的定义。在最好的情况下,SFINAE可以检查是否声明了某个函数。SFINAE不可能确定链接器稍后是否会找到该函数的定义

<>如果C库带有头,可以包含在C++中,并且只有当C库的特定版本定义它们时,才可以声明所涉及的函数,可以使用像JAROD42的回答中所描述的AuffoCH。 否则,我在这里能想到的最好的办法就是定义始终定义的函数的默认实现,例如:

struct SomeStruct
{
int指标数;
};
外部“C”void someFun(SomeStruct*somePointer)\属性\属性\属性((弱))
{
//如果C库没有定义此函数,请执行此操作
}

弱符号不是标准C++的一部分,所以执行此操作的确切机制取决于编译器和平台。以上是GCC的一个例子。MSVC有一个未记录的链接器标志

/alternatename
,允许为符号提供默认定义,请参阅


在链接过程中,如果链接器发现来自C库的同一符号的非弱定义,它将选择该符号,否则它将选择默认实现…

您可以使用优先级较低的重载来解决问题:

// "C-Header"
struct SomeStruct
{
  int indicatorMember;
};

// Present or not
extern "C" void someFun(struct SomeStruct* somePointer){

}

// Fallback
void someFun(...) { /*Empty*/ }

void someCPPcode()
{
  SomeStruct s;
  // do something

  someFun(&s);

  // do something other
}
如果某个构件是结构的一部分,也可以确定该功能是否存在。因此,如果
indicatorMember
确实存在,则该函数也存在

有几种方法可以检测成员的存在,例如使用

但在模板之外,您仍然存在以下问题:

decltype(auto) someFunIfExists([[maybe_unused]] SomeStruct* p)
{
    if constexpr (has_someFunc<SomeStruct>::value) {
        return someFun(p); // Not discarded as you might expect -> Error
    }
}

如果C++代码自动生成,难道你不能把这个逻辑包含在生成器本身中吗?也就是说,只有在C源代码中可以找到函数时才能生成调用。您可能会在这个链接中找到一些提示:这是否回答了您的问题?如果你有一些结构指标方法/字段,那么在链接的问题中有SFINAE方法。@DanM。生成器不知道c源。它使用的定义语言不包含这些信息,问题在于它仍然是一个声明哪些函数的问题,而不是什么函数有定义的问题。如果C库不定义函数……不确定“输入”(我们有C标题,OP是否生成C++代码,……),那么您将不得不使C库函数的所有声明都消失。
template <typename T>
decltype(auto) someFunIfExists([[maybe_unused]] T* p)
{
    if constexpr (has_someFunc<T>::value) {
        return someFun(p);
    }
}

void someCPPcode(){
  SomeStruct s;
  // do something

  someFunIfExists(&s);

  // do something other
}