Thread: How to link a dll to my c program

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    27

    How to link a dll to my c program

    Hi I have an old inherited file with c code (visual studio 6). I compiled this file in Visual C++ 2010 (I made a solution and a win32 console application) and was ok. But when I did the build to make the .exe then the linker throws errors. I found that was missing a dll. But how can I link the dll in visual C++ 2010; I have a .dll and the corresponding .lib file from manufacturer. How can I go?

    Thanks

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Posting some actual error messages, and not just empty "there are errors", would be a big help (I guess).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    add the .lib file to the linker 'input' configuration in the project properties

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    27
    Quote Originally Posted by Salem View Post
    Posting some actual error messages, and not just empty "there are errors", would be a big help (I guess).
    The question was about the link to a .dll and .lib not the interpretation of errors.
    Anyway I copy-paste them:

    ctconnectAPI.obj : error LNK2019: unresolved external symbol _ctcErrMsg@4 referenced in function _main
    1>ctconnectAPI.obj : error LNK2019: unresolved external symbol _ctcSetMonitor@8 referenced in function _start_monitoring
    1>ctconnectAPI.obj : error LNK2019: unresolved external symbol _ctcAssign@20 referenced in function _start_monitoring
    1>ctconnectAPI.obj : error LNK2019: unresolved external symbol _ctcDeassign@4 referenced in function _stop_monitoring
    1>ctconnectAPI.obj : error LNK2019: unresolved external symbol _ctcGetEvent@12 referenced in function _get_event

  5. #5
    Registered User
    Join Date
    Nov 2011
    Posts
    27
    Quote Originally Posted by dmh2000 View Post
    add the .lib file to the linker 'input' configuration in the project properties
    Because I do not know Visual C++ 2010 I would appreciate a step by step approach if am not cumbrous...
    And where the .dll relates to all these if I need only the .lib?
    thanks..

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Unresolved symbols mean you didn't configure the IDE to look in the right place for the right libraries.

    > But how can I link the dll in visual C++ 2010;
    It probably starts with project->settings->linker->additional libraries
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    And where the .dll relates to all these if I need only the .lib?
    x.lib is the import library file for x.dll. You add x.lib to the "additional dependencies" for the linker. x.dll is dynamically linked, so if its location is not in the PATH environment variable then it must be in the program root directory.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  8. #8
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    I have a similar problem. I have a project ????.vcproj. I can open it in Microsoft Visual Studio and change and compile the .cpp source. Somehow, somewhere, the original programmer managed to attach a DLL to make it run - it is a vendor`s black box. I have never been able to find how to attach the same DLL to my own program if I were to create a new project. Where in the confusing mess of Microsoft Visual Studio 2005 can I find the DLL reference, its name, path, etc.?
    I've tried and tried documentation, searches on internet, etc. Everybody loves to explain how wonderful DLL is but no one explains how to make it work.

  9. #9
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    So you're saying that you have a project that works with the dll and runs fine and you want to know how to reuse the same dll in another project?

    That depends. If it's accessed in the code with functions like LoadLibrary and GetProcAddress then you should be able to do the same in the other project.

    But if it has an associated .lib file then you need to find that, under linker dependencies (or some such) and add it to the other project.

    There might also be an associated module definition file (ends in .def).

    And of course the header file needs to be included.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  10. #10
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Thanks oogabooga. What I need is some hand-holding... someone to tell me exactly where to click, drag-down, etc. so I can see where the DLL is mentioned. Yes the program has prototypes for the functions and it calls them. I just never figured out how and where to tell the Visual Studio the name and location of the DLL. Anyway, solving my problem may be relevant to the OP's issue as well.

  11. #11
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    Personally, I always prefer LoadLibrary and GetProcAddress, even for DLL's for which I have the lib on hand. It's too easy for something to change or to make your development environment more difficult to move around. At least with those functions, I can see what's inside a DLL or not too, and manually pick out the right functions or warn if they aren't there.

    When SDL 1.2 becomes obsoleted by SDL 2.0, for instance, there's going to be a lot of people finding that they have to recompile everything even if the code itself works portably in the new version.

    And it's much nicer to generate your own error messages when either of those functions fail rather than rely on the operating system to give some obscure error because some 3rd-order dependency on a DLL that the user doesn't have failed to load. At least you can give them a hint as to what's missing, where to find it, where you were looking for it etc. when they run your final binary rather than just a fatal error.

    I know as a user I'd much rather see:

    "Could not load XXXXX.dll. This is normally part of the XXXXX package that you can install from here: URLURLURL."

    or

    "XXXXXX.dll is the wrong version. I advise you not to continue. Do you want me to try to continue anyway? Yes/No"

    Or:

    "Could not find DLL's required for audio. Audio is disabled."

    or even:

    "Could not find the SDL DLL's. Please reinstall the program."

    rather than

    "Fatal error"


    I also like to check that if I bundle a DLL, e.g. SDL, that I check for its prerequisites too. It's all too easy to bundle an upgrade to the version of SDL used and not realise that you've forgotten to bundle the updated libpng DLL that it relies on, or whatever. It'll probably work fine for a lot of people but someone, somewhere will get stung.

    About the first 5% of my initialisation process is checking DLL's are present, checking the version numbers are the ones I *gave* the user, checking they have the functions I need inside them (all too easy to get DLL's that have been compiled with different options but the same version number - e.g. SDL_Mixer compiled with MP3 support or not, which can crash the program on DLL load if you're not checking for it first), and checksumming the rest of the files I give them (to know they haven't been playing with anything else). Only when all that's done do I start calling functions from those DLL's.

    It's a very good "bug-fixing" habit to get into. Imagine spending hours trying to bugfix an obscure problem on someone's machine only to find out that their SDL.dll from some-other-program was being loaded instead, or that they manually changed the version of your DLL's because they were old or they were trying to hack around some protection. Hell, Cygwin has atrocious problems with things like that when you try to distribute the resulting programs.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  12. #12
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Wow. All Excellent advice. Yet I have no idea how to programmatically check for presence of DLL or its version or its content functions. Perhaps you could message me with the details as this is quickly spiralling out of topic for this thread.
    I hate relying on others' mysterious DLL which is more likely to go flakey than my own code. Yet they protect theirs with costly license agreements worth 10x my salary.

  13. #13
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    LoadLibrary: LoadLibrary function
    GetProcAddress: GetProcAddress function
    FreeLibrary: FreeLibrary function

    or their Linux equivalents:

    dlopen: dlopen
    dlsym: dlsym
    dlclose: dlclose

    The first "opens" a specified DLL. The next loads a named function into a function pointer for you (so you specify the DLL and the function name, and it gives you back an in-memory pointer to that function that you can cast to an appropriate prototype and call just like a normal function). The last "closes" a DLL when you've finished with it and all its functions.

    I consider the second step the most obscure if you're a beginner and have macros and functions I've written to automate things for me. Specifically, say you include a header for a DLL that has a function "Initialise". You need to include that header to get data-types correct, etc. but you can't call the loaded DLL function "Initialise" because that's already prototyped in the header file!

    Code:
    #define PROTOTYPE_DLL_FUNC(retvalue, funcname, params) \
        typedef retvalue(*pf##funcname) params; \
        pf##funcname DLL_##funcname;
    Which you use like so:

    Code:
    PROTOTYPE_DLL_FUNC(int, Initialise, (void *param1, char *param2))
    This gives you a callable function DLL_Initialise which would call the function Initialise inside the DLL with the appropriate return type and parameters (make sure the params are contained in one set of brackets) and not stomp over existing declarations.

    So you PROTOTYPE the function as above. Then you LoadLibrary the DLL (checking for success), then you GetProcAddress the function Initialise within the correct DLL (again, checking for success) and put the result of GetProcAddress straight into DLL_Initialise.

    That's your setup done and from then on in your program, calling DLL_Initialise(...) will work as expected. If you write a C and header file for DLL loading, you can bundle lots of prototypes into the H file along with the above macro and include that file wherever you call a DLL_whatever function. You can stick all the loading, checking, assignment, etc. into the C file, and make one function that checks for prerequisite DLL's and loads all their functions, warns about missing things etc.

    I also have my C file keep track of everything loaded so that at exit, it unloads it all nicely (not strictly necessary but good practice), and it also has a define for Windows/Linux that substitutes dlopen/LoadLibrary as appropriate to work on both OS.

    It also takes care of little gotchas like: Linux uses different filenames for libraries than Windows, Linux functions return a (void *) pointer, Windows one return HANDLE (which is pretty much the same thing, but my #ifdef's handle it all for me without syntax errors), etc.

    When I first wrote it, it seemed an awful lot of faffing about just to call a function. But it's proved invaluable and I've ended up putting it into almost every project I use. And when I upgrade the version of SDL (which I use a lot), or substitute a different but compatible DLL, I just replace the DLL file in the same folder and everything works without a recompile.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help converting array program to link list program
    By hsmith1976 in forum C++ Programming
    Replies: 0
    Last Post: 02-14-2010, 09:50 PM
  2. to link a dictionary to the c program
    By kathireswaran in forum C Programming
    Replies: 1
    Last Post: 10-11-2008, 07:36 AM
  3. an example of c program using singly link list?
    By llinocoe in forum C Programming
    Replies: 1
    Last Post: 09-22-2008, 08:19 AM
  4. LINK LIST program ....Pls HELP....??
    By shubhamjain_007 in forum C Programming
    Replies: 4
    Last Post: 04-19-2008, 11:48 PM
  5. How would you link a program to a DLL?
    By Pro in forum C++ Programming
    Replies: 28
    Last Post: 02-10-2008, 10:12 AM