Template wrapper link query

Discussion in 'C++' started by PGK, Apr 9, 2009.

  1. PGK

    PGK Guest

    I'd like to wrap a series of "C" library functions using instantiated
    templates. I'd also like to have this interface in a header file, but
    not require the user to link to the "C" library.

    In the example below, addInts and addChars are functions stored in a
    "C" library. Running "c++ main.cpp addLib.o" is fine, but "c++
    main.cpp" gives errors relating to the undefined references to addInts
    and addChars.

    As it stands, I have a clear error. Does anyone know if there's a
    workaround?
    Cheers,
    Paul

    // foo.h
    extern "C" int addInts(int,int);
    extern "C" char addChars(char,char);

    template<typename T>
    T myAdd(T a, T b) { return a + b; }
    template<>
    char myAdd(char a, char b) { return addChars(a,b); }
    template<>
    int myAdd(int a, int b) { return addInts(a,b); }

    // main.cpp
    #include "foo.h"
    int main(int argc, char *argv[]){ return 0;}
     
    PGK, Apr 9, 2009
    #1
    1. Advertising

  2. PGK wrote:
    > I'd like to wrap a series of "C" library functions using instantiated
    > templates. I'd also like to have this interface in a header file, but
    > not require the user to link to the "C" library.
    >
    > In the example below, addInts and addChars are functions stored in a
    > "C" library. Running "c++ main.cpp addLib.o" is fine, but "c++
    > main.cpp" gives errors relating to the undefined references to addInts
    > and addChars.


    Well, in the program below they aren't defined. Where *are* they defined?

    >
    > As it stands, I have a clear error. Does anyone know if there's a
    > workaround?
    > Cheers,
    > Paul
    >
    > // foo.h
    > extern "C" int addInts(int,int);
    > extern "C" char addChars(char,char);
    >
    > template<typename T>
    > T myAdd(T a, T b) { return a + b; }
    > template<>
    > char myAdd(char a, char b) { return addChars(a,b); }
    > template<>
    > int myAdd(int a, int b) { return addInts(a,b); }
    >
    > // main.cpp
    > #include "foo.h"
    > int main(int argc, char *argv[]){ return 0;}


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 9, 2009
    #2
    1. Advertising

  3. PGK

    PGK Guest

    On Apr 9, 1:50 pm, Victor Bazarov <> wrote:
    > PGK wrote:
    > > I'd like to wrap a series of "C" library functions using instantiated
    > > templates. I'd also like to have this interface in a header file, but
    > > not require the user to link to the "C" library.

    >
    > > In the example below, addInts and addChars are functions stored in a
    > > "C" library. Running "c++ main.cpp addLib.o" is fine, but "c++
    > > main.cpp" gives errors relating to the undefined references to addInts
    > > and addChars.

    >
    > Well, in the program below they aren't defined.  Where *are* they defined?
    >
    >
    >
    >
    >
    > > As it stands, I have a clear error. Does anyone know if there's a
    > > workaround?
    > > Cheers,
    > > Paul

    >
    > > // foo.h
    > > extern "C" int  addInts(int,int);
    > > extern "C" char addChars(char,char);

    >
    > > template<typename T>
    > > T    myAdd(T a, T b) { return a + b; }
    > > template<>
    > > char myAdd(char a, char b) { return addChars(a,b); }
    > > template<>
    > > int myAdd(int a, int b)         { return addInts(a,b); }

    >
    > > // main.cpp
    > > #include "foo.h"
    > > int main(int argc, char *argv[]){ return 0;}

    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    They are defined in addLib.o
     
    PGK, Apr 9, 2009
    #3
  4. PGK wrote:
    > On Apr 9, 1:50 pm, Victor Bazarov <> wrote:
    >> PGK wrote:
    >>> I'd like to wrap a series of "C" library functions using instantiated
    >>> templates. I'd also like to have this interface in a header file, but
    >>> not require the user to link to the "C" library.
    >>> In the example below, addInts and addChars are functions stored in a
    >>> "C" library. Running "c++ main.cpp addLib.o" is fine, but "c++
    >>> main.cpp" gives errors relating to the undefined references to addInts
    >>> and addChars.

    >> Well, in the program below they aren't defined. Where *are* they defined?
    >>[..]

    >
    > They are defined in addLib.o


    Uh... So, *if* the compiler/linker *knows* where they are (and it does
    when you supply the name of the object module in the command line),
    everything is OK, and if you *don't supply* the name of the object
    module, you get the error... Hm... Tough choice. What should you
    do?... Hm... Don't know what to tell you. Have you tried *not
    omitting* the name of the object module from the command line? Oh, you
    have, haven't you? And it worked. Aha...

    What exactly do you want to hear/read? Isn't this like in the old joke,
    "Doctor, if I remove the name of the .o file from the command line, I
    get the link error. -- Well, don't do that!"

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 9, 2009
    #4
  5. PGK

    PGK Guest

    I thought there might be a way to short-circuit the call to
    addChars/addInts etc. It seems a little redundant to fill a
    function body with only "return addChars(a,b)".
     
    PGK, Apr 9, 2009
    #5
  6. PGK wrote:
    > I thought there might be a way to short-circuit the call to
    > addChars/addInts etc. It seems a little redundant to fill a
    > function body with only "return addChars(a,b)".


    It's fine, it's perfectly acceptable. Of course, it would probably be
    better if you could do (disclaimer: not valid C++):

    template<class T> T addThem(T a, T b) { return a+b; }

    extern "C" char addChar(char a, char b); // from a library
    template<> char addThem<char>(char a, char b) = addChar;

    extern "C" int addInt(int a, int b); // from a library
    template<> int addThem<int>(int a, int b) = addInt;

    Hey, you can always suggest that in 'comp.std.c++' as a possible
    improvement. You only need to figure out a justification. Right now
    what you do should work in all cases, and compiler optimisation will
    most likely replace the calls to 'addThem<char>' with 'addChar' since
    the specialisation is inline for all practical purposes.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 9, 2009
    #6
  7. PGK

    PGK Guest

    On 9 Apr, 18:11, Victor Bazarov <> wrote:
    > PGK wrote:
    > > I thought there might be a way to short-circuit the call to
    > > addChars/addInts etc. It seems a little redundant to fill a
    > > function body with only "return addChars(a,b)".

    >
    > It's fine, it's perfectly acceptable.  Of course, it would probably be
    > better if you could do (disclaimer: not valid C++):
    >
    >     template<class T> T addThem(T a, T b) { return a+b; }
    >
    >     extern "C" char addChar(char a, char b); // from a library
    >     template<> char addThem<char>(char a, char b) = addChar;
    >
    >     extern "C" int addInt(int a, int b); // from a library
    >     template<> int addThem<int>(int a, int b) = addInt;
    >
    > Hey, you can always suggest that in 'comp.std.c++' as a possible
    > improvement.  You only need to figure out a justification.  Right now
    > what you do should work in all cases, and compiler optimisation will
    > most likely replace the calls to 'addThem<char>' with 'addChar' since
    > the specialisation is inline for all practical purposes.
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    I think they've got enough on their plates right now :) Thanks anyway.
    Paul
     
    PGK, Apr 10, 2009
    #7
  8. PGK

    James Kanze Guest

    On Jun 3, 8:50 pm, Paavo Helde <> wrote:
    > PGK <> kirjutas:


    > > I'd like to wrap a series of "C" library functions using
    > > instantiated templates. I'd also like to have this interface
    > > in a header file, but not require the user to link to the
    > > "C" library.


    > Microsoft Visual C++ has #pragma comment(linker, ...) which
    > can be used for linking in the needed libraries whenever the
    > library headers are included. This seems like a feature you
    > are looking for. However, this is an implementation-specific
    > extension and thus off-topic here. I don't know if other
    > compilers provide something similar.


    I don't think they do, but I don't think that solves his
    problem, either. All the pragma does is free the client from
    having to specify the name of the library when linking. The
    library still must be present on the system, somewhere where the
    compiler knows to look (a directory specified by /LIBPATH, or
    the %LIB% environment variable), and the library will still be
    linked into the final executable.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 4, 2009
    #8
  9. PGK

    James Kanze Guest

    On Jun 4, 8:52 pm, Paavo Helde <> wrote:
    > James Kanze <> kirjutas:
    > > On Jun 3, 8:50 pm, Paavo Helde <> wrote:
    > >> PGK <> kirjutas:


    > >> > I'd like to wrap a series of "C" library functions using
    > >> > instantiated templates. I'd also like to have this interface
    > >> > in a header file, but not require the user to link to the
    > >> > "C" library.


    > >> Microsoft Visual C++ has #pragma comment(linker, ...) which
    > >> can be used for linking in the needed libraries whenever the
    > >> library headers are included. This seems like a feature you
    > >> are looking for. However, this is an implementation-specific
    > >> extension and thus off-topic here. I don't know if other
    > >> compilers provide something similar.


    > > I don't think they do, but I don't think that solves his
    > > problem, either. All the pragma does is free the client from
    > > having to specify the name of the library when linking. The
    > > library still must be present on the system, somewhere where the
    > > compiler knows to look (a directory specified by /LIBPATH, or
    > > the %LIB% environment variable), and the library will still be
    > > linked into the final executable.


    > We are guessing what exactly OP wanted. In my mind, to expect
    > to benefit from the library without actually using it is a bit
    > unrealistic,


    But we often have posters asking to do unrealistic things. Just
    because it is unrealistic doesn't mean that that's not what he
    meant.

    > so I assumed that OP just wants to remove the burden of
    > explicit linking from the library users. And this wish is not
    > so improper; when I include library headers, then I definitely
    > want to link against that library, so why should I tell this
    > separately?


    > If the libraries are installed in a common directory there is
    > no problem.


    If different libraries are installed in the same directory, you
    have real problems in managing things. Directories are there
    precisely to keep these things separate.

    > In our Windows build system this mechanism is used for tens of
    > projects with no problems.


    How do you manage which libraries are present, and which aren't?
    How do you remove a library, being sure that all files in the
    library are removed, and no other files?

    Classically, under Unix, the solution was simple: each library
    was put in its own, separate directory, and "rm -r libraryRoot"
    removed it completely, with no risk of removing anything else.
    of course, this typically meant that you needed two path
    commands in the command line, a -IlibraryRoot/include and a
    -LlibraryRoot/lib, plus an additional -lrary to specify the
    library, but in the end, the client programmer does have to know
    (or should know) that he's using the library.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 5, 2009
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kevin Spencer

    Re: Link Link Link DANGER WILL ROBINSON!!!

    Kevin Spencer, May 17, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    956
    Kevin Spencer
    May 17, 2005
  2. Chris Theis
    Replies:
    2
    Views:
    503
    Chris Theis
    Jul 24, 2003
  3. tom_usenet
    Replies:
    0
    Views:
    568
    tom_usenet
    Jul 24, 2003
  4. Simon G Best
    Replies:
    2
    Views:
    441
    Simon G Best
    Sep 25, 2003
  5. Replies:
    1
    Views:
    2,150
    Gianni Mariani
    Jun 8, 2007
Loading...

Share This Page