1

Im creating a library to interface into drawing a specific file type. This library needs to pull in a 3rd party library to do some processing on this specific file type. This 3rd party lib requires the users of it to create some extern functions that it uses to make data types on target hardware.

So, it looks like this:

----------------
|              | 
| 3rd Party    | 
|   Lib        | 
|              | 
----------------
      |
      |
     \/
---------------
|             | 
|  My Lib     | 
---------------
|  externs    | 
---------------
      |
      |
     \/
---------------
|             | 
|  My App     | 
|             | 
|             | 
---------------

My App calls My Lib and says "draw me file X", My Lib does a bunch of junk eventually calling 3rd Party Lib and says "process file X". 3rd Party Lib requires several externs to be declared that it uses.

I made all these externs inside My Lib. My problem is, when I link My App, its telling me undefined references to all the extern functions. I can't figure out why. Heres one of the externs inside My Lib to be called by 3rd Party Lib:

// inside typeConversions.c

extern int CreateShort(short* shortList, int numShorts)
{
    int i;

    for(i = 0; i < numShorts; i++)
    {
        BYTE_SWAP_SHORT(shortList[i]);
    }

    return ERROR_OK;
}

When I link My App I get (among several other similar errors):

open.cpp: undefined reference to `CreateShort'

Where open.cpp is inside the 3rd Party Lib.

I have both My Lib and 3rd Party Lib included in My App. Ideally, I want to not expose users of My Lib to 3rd Party Lib, so for example My App would not have to include 3rd Party Lib at all, they dont know it even exists. All that should be exposed is My Lib. Is this possible? Anyone know how to fix my linking problem?

gooner15
  • 31
  • 1
  • 6

2 Answers2

0

1) Look up "calling conventions" in your compiler and linker documentation. You most likely have a mismatch.

2) In C, (not C++) The extern keyword should be used in the header, not on the function definition. Make sure you include the header in all files that use the declarations, including the .C file that implements what the header declares.

    // This goes in a header file
    extern int CreateShort(short* shortList, int numShorts)

    // This goes in a .c file.
    int CreateShort(short* shortList, int numShorts)
    {
        ...
        return ERROR_OK;
    }

3) If you are using C++ to write the functions that the 3rd party lib calls, and the 3rd party lib expects things to work like C, you'll have to use extern "C" to prevent name mangling.

    // This goes in a header file
    extern "C" int CreateShort(short* shortList, int numShorts)
    // You can also wrap it in a block:
    // extern "C" {
    // int someFunc1( int x );
    // int someFunc2( int y );
    // }

    // This goes in a .cpp file.
    extern "C" int CreateShort(short* shortList, int numShorts)
    {
        ...
        return ERROR_OK;
    }
JimR
  • 15,513
  • 2
  • 20
  • 26
  • This is pure C, I've tried the extern "C" and also declaring extern in the function header. Neither of those solve the problem, thank you though. I'm using Eclipse 3.3.0. I have an app that uses the "3rd Party Lib" direcly, creating the externs in the app itself, that links and runs fine. I need this functionality to be in another library, like I am trying to create, but this does not link. – gooner15 Nov 29 '10 at 21:14
  • @gooner15 OK. Look at your compiler docs for calling conventions. Eclipse is not a compiler nor a linker as far as I know. :) Unless it has fallen into the Emacs Zone. If you're on Linux, try man gcc or info gcc and search for calling convention. Then look at the 3rd party library headers and see what calling convention they expect. – JimR Nov 29 '10 at 21:17
  • Ok, I guess I'm not sure what I'm supposed to be looking for, as calling convention seems to only deal with cross-language calling? I'm using Cygwin in Eclipse, gcc toolchain with lynxos cross compiler. Sorry, I've never had linking issues like this before and I don't really know where to look. – gooner15 Nov 29 '10 at 22:38
  • @gooner15 There has to be some standard for how things are named, arguments passed to functions, who pops the stack upon return etc, etc, etc. This stuff is defined by the calling convention. Look at the function prototypes in the 3rd party lib headers and see if there are any __attribute__ statements and post them here. I am not sure what the lynxos default calling convention is, so if you can figure that out it would help narrow down the issues. – JimR Nov 30 '10 at 09:00
0

Seems like my problem was that I didnt have the header file containing my externs "visible" enough for the linker to see when linking the app. I have several folders in my library workspace, moving the header file to the top of this heirarchy fixed my issue. Weird!

gooner15
  • 31
  • 1
  • 6