7

I'm looking to declare the type of an extern "C" function pointer. It is a member variable. The syntax in this question I cannot get to compile.

template<typename Sig> struct extern_c_fp {
    extern "C" typedef typename std::add_pointer<Sig>::type func_ptr_type;
};

I have experimented with placing the extern "C" at both ends, and between typedef and typename and between type and func_ptr_type, but the compiler rejected all. Any suggestions?

Community
  • 1
  • 1
Puppy
  • 144,682
  • 38
  • 256
  • 465
  • With `extern "C"` alias templates, this would work. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1463 – Johannes Schaub - litb Nov 03 '12 at 22:00
  • 2
    BTW You need `Sig` to be `extern "C"`. The pointer addition to the function type does not have the linkage. It's the function type itself. You induce the linkage when forming the function type. Not when naming an existing function type - that existing type has the linkage it has. – Johannes Schaub - litb Nov 03 '12 at 22:01
  • http://liveworkspace.org/code/768027ef00bb0a31e76d8d856ac50801 It complains less, but still problematic. – Puppy Nov 03 '12 at 22:07
  • Unfortunately `extern "C" { template struct A {}; }` is rejected by implementations. Instead of not applying the linkage to `A`, they try to apply it and violate the rule that templates shall not have C language linkage. IMHO such code is valid... language linkage does not apply to templates and hence the template will never have C language linkage. Such code would be useful! – Johannes Schaub - litb Nov 03 '12 at 22:17
  • 1
    Am I missing something here. Why are you trying to do this? – doron Nov 03 '12 at 22:23
  • Is it possible to give C linkage to C++ methods/member functions or am I missing something? At first glance, it doesn't quite make sense to me. –  Nov 03 '12 at 22:48
  • It has nothing to do with a C++ method or member function. It's about having a member variable that is a function pointer, with the extern "C" calling convention. – Puppy Nov 04 '12 at 00:10

2 Answers2

1
extern "C" {
    template<typename R, typename... Args>
    using extern_c_fp = R(*)(Args...);
}

using my_function_ptr = extern_c_fp<void, int, double>;
// returns void, takes int and double

This doesn’t use the same interface as you use, but there may be a way to extract the return type and argument types of Sig.

This works in clang 3.1. Xeo pointed out it didn’t work in GCC. I’m not sure if this is a bug in either compiler, so be careful when using this.

Community
  • 1
  • 1
0

You cannot declare a typedef like that (from 7.5p4):

A linkage-specification shall occur only in namespace scope (3.3).

Jesse Good
  • 50,901
  • 14
  • 124
  • 166