CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: Linking Error

  1. #1
    Join Date
    Feb 2003
    Location
    Texas
    Posts
    8

    Linking Error

    I am trying to use Adobe's FDF Toolkit to generate a FDF file to populate a PDF. I have their .h, .lib, and. dll are have put them all in the correct places; they are all in my path. However, when I compile my cpp, I get linking errors:

    error LNK2029: "?FDFSetFile" : unresolved external
    error LNK2029: "?FDFSetValue" : unresolved external
    error LNK2029: "?FDFSave" : unresolved external
    error LNK2029: "?FDFClose" : unresolved external
    error LNK2029: "?FDFCreate" : unresolved external

    Why is this? The library is there, it just isn't recognizing it.

    I am using IBM's Visual Age C++ on a WinNT System. Could there be a problem that the adobe libs were compiled with a different c++ compiler than me? Maybe I'm not linking correctly? Maybe I'm not compiling correctly? Is it case sensitive?

    Any help would be greatly appreciated.

  2. #2
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443

    Re: Linking Error

    Originally posted by Jen P
    Could there be a problem that the adobe libs were compiled with a different c++ compiler than me?
    I guess that if this was the case, your linker would warn you that it doesn't understand the library format. Just a guess, though, as I don't know IBMs compiler.
    Gabriel, CodeGuru moderator

    Forever trusting who we are
    And nothing else matters
    - Metallica

    Learn about the advantages of std::vector.

  3. #3
    Join Date
    Feb 2003
    Location
    Bilbao
    Posts
    513
    Check this two things:

    1. Have you added the .lib to your project?

    2. Try copying .dll into your windows/system directory (in Winnt I think it is system32...)
    Caronte
    Si tiene solución... ¿por qué te preocupas?
    Si no tiene solución... ¿por qué te preocupas?

  4. #4
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    If the library was created with object files created from a C++
    compiler, then you would get the mangled functions in your library
    and then your C++ compiler might not be able to understand
    them.

    However, if the library file was created by a C compiler, then it's
    my guess that your compiler is compiling the functions as if they're
    C++ functions [complete with mangling] and that is why the linker
    cannot find them. So, try doing wrapping the header file you're
    #include'ing with extern "C"; if you cannot modify the given
    header file, I think you can include another one that does the
    extern for you:
    Code:
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    #include "yourHeader.h"
    #ifdef __cplusplus
    }
    #endif
    I'm not sure about that above "code"; I don't know how the
    preprocessor #include woudl be included AFTER the extern was
    referenced.... So, if the above doesn't work, then just edit the
    header file you have and add the extern "C" manually.

    That's just an idea, though.

    --Paul

  5. #5
    Join Date
    Oct 2002
    Location
    Da Lian
    Posts
    11

    Re: Linking Error

    Try this:
    Add the instruction in the front of your program:

    #pragma comment(lib, "your lib path and name")
    Do not,for one repulse,give up the purpose that you resolved to effect.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Linking Error

    Originally posted by Jen P
    I am trying to use Adobe's FDF Toolkit to generate a FDF file to populate a PDF. I have their .h, .lib, and. dll are have put them all in the correct places; they are all in my path. However, when I compile my cpp, I get linking errors:

    error LNK2029: "?FDFSetFile" : unresolved external
    error LNK2029: "?FDFSetValue" : unresolved external
    error LNK2029: "?FDFSave" : unresolved external
    error LNK2029: "?FDFClose" : unresolved external
    error LNK2029: "?FDFCreate" : unresolved external

    Why is this? The library is there, it just isn't recognizing it.

    I am using IBM's Visual Age C++ on a WinNT System. Could there be a problem that the adobe libs were compiled with a different c++ compiler than me? Maybe I'm not linking correctly? Maybe I'm not compiling correctly? Is it case sensitive?

    Any help would be greatly appreciated.
    You say you have the ".lib" file, but do you know which compiler produced the file? Import libraries are compiler dependent, so a VC++ lib file may not work for an IBM compiler. I know a VC++ lib file will not work for a C++ Builder or Borland compiler.

    To get around these issues, your best bet is to forget about the lib file and use the tried and true method that works all the time -- and that is to use LoadLibrary and GetProcAddress. If you are not familiar with these functions, basically LoadLibrary loads the DLL at runtime, and GetProcAddress returns a function pointer to one of the exported functions. So in your case, if the Adobe Library is called ADOBE32.DLL, and the function is FDFSetFile which takes one LPCSTR parameter and returns an int, this will work:
    Code:
    #include <windows>
    typedef int (*FDFSETFILEFUNC)(LPCSTR);
    
    int main()
    {
        FDFSETFILEFUNC pFunc=NULL;
        HMODULE hMod = LoadLibrary( "ADOBE32" );
        if ( hMod )
        {
             pFunc = (FDFSETFILEFUNC)GetProcAddress("FDFSetFile");
             if (pFunc)
             {
                    // Call the FDFSetFile function
                    (*pFunc)("Test");
             }
             else
             {
                   // Exported function called "FDFSetFile" does not exist
             }
             // Free the library when done
             FreeLibrary( hMod );
        }
        else
        {
             // Library could not load
        }
    }
    Of course, this is just an illustration of just calling one function. There are C++ classes that you can find on the net that encapsulate the LoadLibrary / GetProcAddress / FreeLibrary approach to handling DLL's.

    This is how my company tests the DLL's we create against different C++ compilers. Instead of wasting time trying to figure out how each compiler handles .lib files, all we need to do is to compile the code with no .lib file and everything falls into place.

    You should load the Adobe DLL into Dependency Walker or some other utility that lists the exported functions. When you use GetProcAddress, your function name must match exactly (including case-sensitivity) with the name that is exported from the DLL. If not, GetProcAddress will return NULL.

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Feb 2003
    Location
    Texas
    Posts
    8
    Thanks so much for all your suggestions. I tried them all; the last post from Paul McKenzie worked!!

    However, when I run my executable, I get errors. Does anyone know how I can look into these problems?

    General Protection Fault exception occurred at EIP = 10001C1D on thread 016A.
    Register Dump at point of exception:
    EAX = 0137DA1F EBX = 10062900 ECX = 10000000 EDX = 77FA5560
    EBP = 0003FF6C EDI = 00000000 ESI = F9A00035 ESP = 0003FF08
    _CS = 001B CSLIM = FFFFFFFF DS = 0023 DSLIM = FFFFFFFF
    _ES = 0023 ESLIM = FFFFFFFF FS = 0038 FSLIM = 00000FFF
    _GS = 0000 GSLIM = 00000000 SS = 0023 SSLIM = FFFFFFFF
    NPX Environment:
    CW = 0262 TW = FFFF IP = 0000:00000000
    SW = 0000 OPCODE = 0000 OP = 0000:FFFF0000
    NPX Stack:
    No valid stack entries.
    Process terminating.

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by Jen P
    Thanks so much for all your suggestions. I tried them all; the last post from Paul McKenzie worked!!

    However, when I run my executable, I get errors. Does anyone know how I can look into these problems?
    Ok. Let us know where the error occurs. Is it when you make a call to a DLL function? If so, is it the first call to the DLL?

    The reason why I ask is that you may have to declare your function pointers a little differently. I'm assuming that the Adobe functions are __stdcall (check the header file for the function prototypes). If so, your function pointer signatures should be declared with the __stdcall modifier also. If the failure appeared with the very first DLL call, this is a good indication that either the function wasn't declared properly, or (of course) you just didn't call your function correctly

    Use the Dependency Walker utility (hopefully you have this program that allows you to look into a DLL's exported functions). I believe you can get it free on the Internet if you don't have it (or programs similar to Dependency Walker). You need to establish whether the functions are stdcall or cdecl (the other calling convention). If they are stdcall, then you need to change the prototype of the function pointers to the following:
    Code:
    typedef int __stdcall (*FUNCPTR)(params);
    (Hopefully that's correct).

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Feb 2003
    Location
    Texas
    Posts
    8
    I walked though the debug and found that it only has problems with 3 of the 5 functions called. FDFCreate and FDFSetValue are ok. I've attached my cpp and the loaded library's header file.

    I have never used Dependency Walker before, but I have downloaded it now and will look into it. When I run it in Dependency Walker, this is the last thing it shows in the log view:

    Second chance exception 0xC0000005 (Access Violation) occurred in "FDFTK.DLL" at address 0x10010209.
    Exited "U13PDFRPT.EXE" (process 0x179) with code 128 (0x80).

    Not really sure what to do with that information.

    Thanks.
    Attached Files Attached Files
    Last edited by Jen P; March 3rd, 2003 at 12:56 PM.

  10. #10
    Join Date
    Sep 2002
    Location
    Maryland - Fear The Turtle!
    Posts
    7,537
    Are you sure the Create is working? You are getting a pointer to a new FDFDoc returned?

    And the typedefs should read:

    Code:
    typedef int (__stdcall *FDFCREATEFUNC)(FDFDoc);
    typedef int (__stdcall *FDFSETFILEFUNC)(FDFDoc, LPCSTR);
    typedef int (__stdcall *FDFSETVALUEFUNC)(FDFDoc, LPCSTR, LPCSTR, BOOL);
    typedef int (__stdcall *FDFSAVEFUNC)(FDFDoc, LPCSTR);
    typedef int (__stdcall *FDFCLOSEFUNC)(FDFDoc);

  11. #11
    Join Date
    Feb 2003
    Location
    Texas
    Posts
    8

    Thanks!! That totally worked. My create was returning an empty pointer.

    Thanks for everyone's help. I really appreciate it. This has been a wonderful forum experience

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by Mick_2002
    And the typedefs should read:

    Code:
    typedef int (__stdcall *FDFCREATEFUNC)(FDFDoc);
    typedef int (__stdcall *FDFSETFILEFUNC)(FDFDoc, LPCSTR);
    typedef int (__stdcall *FDFSETVALUEFUNC)(FDFDoc, LPCSTR, LPCSTR, BOOL);
    typedef int (__stdcall *FDFSAVEFUNC)(FDFDoc, LPCSTR);
    typedef int (__stdcall *FDFCLOSEFUNC)(FDFDoc);
    Thanks Mick_2002. I knew the __stdcall went somewhere, but didn't remember exactly where. We wrap all of this junk in macros, and I didn't have the source handy, so I guessed (wrong).

    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Sep 2002
    Location
    Maryland - Fear The Turtle!
    Posts
    7,537
    heh...I just like coming into the problem at the end, posting a small typo correction and getting the thanks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured