Topic: Extended use of extern "C


Author: "Gene Bushuyev" <spam@smapguard.com>
Date: 18 Aug 2005 22:50:02 GMT
Raw View
"Ian" <ian-news@hotmail.com> wrote in message
news:42FCFC30.20804@hotmail.com...
>
.
> In the real code there are a large number of callbacks to assign and I
> only want to write the assignment code once, hence the use of function
> templates.

Ok, if you don't like wrappers, you can use template function as a callback
for C code, just drop extern "C" from the callback declaration. I assume the
pointers to the free functions (or static member functions) have the same
size and calling convention both in C and C++ as long as they are compiled
with the same compiler (Let those who intimately know both C and C++
standards comment on that.) I know that the following compiles and works
correctly on seven different platforms with seven different compilers.
//---- example ----
//------------------
//in some.h file:
//------------------
// don't use extern "C" for typedef
typedef void (*callback)();

#ifdef _cplusplus
extern "C"
#endif
void call_callback(callback f);

//------------------
// in some.c file:
//------------------
#include "some.h"
void call_back(callback f) { f(); }

//------------------
//in some_other.cpp file:
//------------------
#include "some.h"

template<class T>
void template_callback();

template<class T>
void test_callback()
{
    // now C code will execute C++ template
    call_callback(&template_callback<T>);
}
//---- end example ----

- gene

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ian-news@hotmail.com (Ian)
Date: Fri, 19 Aug 2005 04:59:29 GMT
Raw View
Gene Bushuyev wrote:
> "Ian" <ian-news@hotmail.com> wrote in message
> news:42FCFC30.20804@hotmail.com...
>
> .
>
>>In the real code there are a large number of callbacks to assign and I
>>only want to write the assignment code once, hence the use of function
>>templates.
>
>
> Ok, if you don't like wrappers, you can use template function as a callback
> for C code, just drop extern "C" from the callback declaration. I assume the
> pointers to the free functions (or static member functions) have the same
> size and calling convention both in C and C++ as long as they are compiled
> with the same compiler (Let those who intimately know both C and C++
> standards comment on that.) I know that the following compiles and works
> correctly on seven different platforms with seven different compilers.
> //---- example ----
> //------------------
> //in some.h file:
> //------------------
> // don't use extern "C" for typedef
> typedef void (*callback)();
>
This works fine, but what if (as in my case) you are working with a C
API (which you don't control)?  In this case, you are stuck with the
extern "C".

Would it be possible to modify the standard to accept function templates
for extern "C" callbacks?  Same question applies to point 2 in my
original post.


Ian

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: spam@spamguard.com ("Gene Bushuyev")
Date: Sat, 20 Aug 2005 05:19:50 GMT
Raw View

--
----------------------------------------------------------------
In the name of God, stop a moment, cease your work, look around you. ~ Leo
Tolstoy
"Ian" <ian-news@hotmail.com> wrote in message
news:43053961.6080106@hotmail.com...
> Gene Bushuyev wrote:
>> "Ian" <ian-news@hotmail.com> wrote in message
>> news:42FCFC30.20804@hotmail.com...
>>
>> .
>>
>>>In the real code there are a large number of callbacks to assign and I only
>>>want to write the assignment code once, hence the use of function templates.
>>
>>
>> Ok, if you don't like wrappers, you can use template function as a callback
>> for C code, just drop extern "C" from the callback declaration. I assume the
>> pointers to the free functions (or static member functions) have the same
>> size and calling convention both in C and C++ as long as they are compiled
>> with the same compiler (Let those who intimately know both C and C++
>> standards comment on that.) I know that the following compiles and works
>> correctly on seven different platforms with seven different compilers.
>> //---- example ----
>> //------------------
>> //in some.h file:
>> //------------------
>> // don't use extern "C" for typedef
>> typedef void (*callback)();
>>
> This works fine, but what if (as in my case) you are working with a C API
> (which you don't control)?  In this case, you are stuck with the extern "C".
>

Well, the only difference is that it requires an explicit conversion:

extern "C"
{
    typedef void (*F)();
    void call(F f) { f(); }
}

template<class T>
void foo();

int main()
{
    call(F(&foo<int>));
}

> Would it be possible to modify the standard to accept function templates for
> extern "C" callbacks?  Same question applies to point 2 in my original post.

The same solution is applicable to your second question: use explicit cast to
convert the pointers. It may not look nice, but as long as there is a simple
solution I don't think there will be much support for amending the standard.

- gene

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ian-news@hotmail.com (Ian)
Date: Sat, 13 Aug 2005 06:32:57 GMT
Raw View
Gene Bushuyev wrote:

 >> Point 1:  It should be possible to declare a function template as
extern "C".  I understand that it would be impossible to directly call
an instantiation or specialisation of a function template from C, but it
should be possible to assign to a C function pointer to enable C code to
indirectly call.
 >
 >
 >
 > Your first problem doesn't require modification of the language. Wrap
the template function call into a function with C linkage, e.g.
 > // functions from C file
 > extern "C"
 > {
 >     typedef void (*Fn)();
 >     void Fc(Fn);
 > }
 >
That's precisely what I am trying to avoid!  I am working with a C
driver API where I'd like to use function templates to setup callbacks,
for example:

extern "C"
{
   struct CbStruct*
   {
     void (*open)(void*);
   };
}

template <typename Driver>
void open( void* p )
{
   Driver().open( p );
}

template <typename Driver>
void setCallbacks( CbStruct* cb )
{
   cb.open = open<Driver>;
}

Here, the function template is being used as a wrapper for a class member.

In the real code there are a large number of callbacks to assign and I
only want to write the assignment code once, hence the use of function
templates.

Ian

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 16 Aug 2005 13:24:56 GMT
Raw View
ian-news@hotmail.com (Ian) writes:

> (repost with valid address)
> Some background:
>
> I have bee integrating a C++ module into a C application.  I have
> encountered two issues I think should be changed with the use of extern "C".
>
> Point 1:  It should be possible to declare a function template as extern
> "C".  I understand that it would be impossible to directly call an
> instantiation or specialisation of a function template from C, but it
> should be possible to assign to a C function pointer to enable C code to
> indirectly call.

I've had the same problem.  IIRC some smart person in the core working
group pointed out to me that you can get the right effect by using
static member function templates in an extern "C" struct.  I never got
around to exploiting it, though.  Please let me know your results if
you try it.

HTH,
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ian@ianshome.com (Ian Collins)
Date: Wed, 17 Aug 2005 03:01:55 GMT
Raw View
David Abrahams wrote:
 >>
 >>Point 1:  It should be possible to declare a function template as extern
 >>"C".  I understand that it would be impossible to directly call an
 >>instantiation or specialisation of a function template from C, but it
 >>should be possible to assign to a C function pointer to enable C code to
 >>indirectly call.
 >
 >
 > I've had the same problem.  IIRC some smart person in the core working
 > group pointed out to me that you can get the right effect by using
 > static member function templates in an extern "C" struct.  I never got
 > around to exploiting it, though.  Please let me know your results if
 > you try it.
 >
No luck, assuming I understand what you are suggesting correctly:

extern "C"
{
  struct Ops
  {
    void (*fn)(int);
  };

  struct Indirect
  {
    template <typename T> static void fn( int n ) { T::fn( n ); }
  };
}

gcc /tmp/x.cc
/tmp/x.cc:10: template with C linkage

CC /tmp/x.cc
"/tmp/x.cc", line 10: Error: Template declarations cannot have extern
"C" linkage.

It's still a template, no matter how well hidden!

Ian

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ian-news@hotmail.com (Ian)
Date: Sun, 7 Aug 2005 01:29:12 GMT
Raw View
(repost with valid address)
Some background:

I have bee integrating a C++ module into a C application.  I have
encountered two issues I think should be changed with the use of extern "C".

Point 1:  It should be possible to declare a function template as extern
"C".  I understand that it would be impossible to directly call an
instantiation or specialisation of a function template from C, but it
should be possible to assign to a C function pointer to enable C code to
indirectly call.

Point 2: It should be possible to use extern "C" at namespace of class
level.  This would enable a typedef to a C function pointer to be
defined within a class.  For example:

template <typename T>
struct Demo
{
   typedef extern "C" void (*SetFn)(T);

   SetFn set;
};

Currently I have to use

template <typename T,
           typename SetFn>
struct Demo
{
   SetFn set;
};

And typedef very instance of SetFn before use.

Comments?

Ian.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: spam@spamguard.com ("Gene Bushuyev")
Date: Sun, 7 Aug 2005 19:49:52 GMT
Raw View
"Ian" <ian-news@hotmail.com> wrote in message
news:1123374755.234406@drone2-svc-skyt.qsi.net.nz...
> (repost with valid address)
> Some background:
>
> I have bee integrating a C++ module into a C application.  I have
> encountered two issues I think should be changed with the use of extern
> "C".
>
> Point 1:  It should be possible to declare a function template as extern
> "C".  I understand that it would be impossible to directly call an
> instantiation or specialisation of a function template from C, but it
> should be possible to assign to a C function pointer to enable C code to
> indirectly call.

Your first problem doesn't require modification of the language. Wrap the
template function call into a function with C linkage, e.g.
// functions from C file
extern "C"
{
    typedef void (*Fn)();
    void Fc(Fn);
}

template<class T> void Ft();

extern "C" inline void wrapper() { Ft<int>(); }

void test()
{
     Fc(&wrapper);
}

- gene

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]