Linker Error when attempting to use binary external library - visual-c++

I am new to C++, having recently taken a class to introduce me to the language, so I understand the basics of the syntax, but there was no discussion of how to use external libraries and connect them to our code.
I am trying to use the CLP COIN library for solving linear programs from...
http://www.coin-or.org/Clp/userguide/clpuserguide.html#id4766717
From what I read there, it suggested to use the precompiled binary libraries rather than download the source, since I am on Windows 7 platform, as they suggested recompiling on Windows can sometimes introduce problems.
I am simply trying to get the equivalent of Hello World working. Here is the sample code they provided to test with...
* Copyright (C) 2004, International Business Machines Corporation
and others. All Rights Reserved.
This sample program is designed to illustrate programming
techniques using CoinLP, has not been thoroughly tested
and comes without any warranty whatsoever.
You may copy, modify and distribute this sample program without
any restrictions whatsoever and without any payment to anyone.
*/
/* This shows how to provide a simple picture of a matrix.
The default matrix will print Hello World
*/
#include "ClpSimplex.hpp"
int main (int argc, const char *argv[])
{
ClpSimplex model;
int status;
// Keep names
if (argc<2) {
status=model.readMps("hello.mps",true);
} else {
status=model.readMps(argv[1],true);
}
if (status)
exit(10);
int numberColumns = model.numberColumns();
int numberRows = model.numberRows();
if (numberColumns>80||numberRows>80) {
printf("model too large\n");
exit(11);
}
printf("This prints x wherever a non-zero elemnt exists in matrix\n\n\n");
char x[81];
int iRow;
// get row copy
CoinPackedMatrix rowCopy = *model.matrix();
rowCopy.reverseOrdering();
const int * column = rowCopy.getIndices();
const int * rowLength = rowCopy.getVectorLengths();
const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
x[numberColumns]='\0';
for (iRow=0;iRow<numberRows;iRow++) {
memset(x,' ',numberColumns);
for (int k=rowStart[iRow];k<rowStart[iRow]+rowLength[iRow];k++) {
int iColumn = column[k];
x[iColumn]='x';
}
printf("%s\n",x);
}
printf("\n\n");
return 0;
}
I have associated the Include and Lib directories with my project in Visual Studio, but when I attempt to build, get a number of linker errors such as:
Simplex(void)" (??1ClpSimplex##QAE#XZ) referenced in function _main
1>hello.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall CoinPackedMatrix::~CoinPackedMatrix(void)" (??1CoinPackedMatrix##UAE#XZ) referenced in function _main
1>hello.obj : error LNK2019: unresolved external symbol "public: void __thiscall CoinPackedMatrix::reverseOrdering(void)" (?reverseOrdering#CoinPackedMatrix##QAEXXZ) referenced in function _main
1>hello.obj : error LNK2019: unresolved external symbol "public: __thiscall CoinPackedMatrix::CoinPackedMatrix(class CoinPackedMatrix const &)" (??0CoinPackedMatrix##QAE#ABV0##Z) referenced in function _main
1>hello.obj : error LNK2019: unresolved external symbol "public: int __thiscall ClpSimplex::readMps(char const *,bool,bool)" (?readMps#ClpSimplex##QAEHPBD_N1#Z) referenced in function _main
1>hello.obj : error LNK2019: unresolved external symbol "public: __thiscall ClpSimplex::ClpSimplex(bool)" (??0ClpSimplex##QAE#_N#Z) referenced in function _main
As a newbie, I am clueless as to how to approach resolving this issue, since my course only covered debugging associated with code syntax, not linker issues.
Any tips or links to other threads would be of great help. I have been Googling all day, but am at a loss...

I'm not sure exactly what you did to associate the Lib directories with the project, but you'll need to make sure that these are done (the first is often overlooked):
You need to add the library filename to the Project's "Linker/Input/Additional Dependencies" property.
You might also need to place the location of the library in the Project's "Linker/General/Additional Library Directories" property - depending on if you give the proper path or just the filename ion the above property. This is probably what you already did.
Update:
In the dumpbin output you posted, you'll see the following entry:
4C3 0000AE4A SECT98 notype () External | ?readMps#ClpSimplex##QEAAHPEBD_N 1#Z (public: int __cdecl ClpSimplex::readMps(char const *,bool,bool))
In the error message, you'll see this:
1>hello.obj : error LNK2019: unresolved external symbol "public: int __thiscall ClpSimplex::readMps(char const *,bool,bool)" (?readMps#ClpSimplex##QAEHPBD_N1#Z) referenced in function _main
Compare the de-mangled names from the two messages:
public: int __cdecl ClpSimplex::readMps(char const *,bool,bool) // what's in the .lib
public: int __thiscall ClpSimplex::readMps(char const *,bool,bool) // what hello.obj is asking for
You'll see that the two calling conventions are different. Looking on the coin-or.org website, it looks like the library was built with VC 2005. For Microsoft compilers, the libraries cannot always be used with different compiler versions. I suggest that you use VC 2005 if you want to use this pre-built library (you should still be able to get the free Express version here: http://go.microsoft.com/fwlink/?linkid=57034).
FWIW, I tried compiling the example with several MS compilers and got the following results (build only - the program complains about some file being missing when I try to run it:
worked: VC 2005 and VC 2008
failed: VC 6 and VC2010

Related

Dynamic Linker does not resolve symbol although the library is already loaded

I stumbled over the following problem in my large-grown project: I have a set of libraries which depend on each other and on external libraries. Of one dependency ("libvtkCommonCore-*.so"), there are different variants, which need to be used interchangeably. The variants have different suffixes ("libvtkCommonCore-custom1.so", "libvtkCommonCore-custom2.so" and so on). Thus I cannot link the library, which needs symbols from it, directly to the providing library. Rather I link the application of the library which uses it to the appropriate variant and then load my own library.
This approach generally works but fails under some circumstances and I'm a bit lost while finding out what goes wrong.
This situation is working:
Sketch of situation 1
("libA" needs symbols from "libvtkCommonCore". It is loaded at run time by the constructor of some static object in "libB" using a "dlopen" call with flags RTLD_LAZY|RTLD_GLOBAL. libvtkCommonCore* and libB were linked at build time to an executable)
This situation now ceases to work:
Sketch of situation 2
(actually the same as before but complicated by the fact that libvtkCommonCore* and libB are linked to another library libC at build time. This library is loaded from an executable at run time using "dlopen")
I investigated the case by setting LD_DEBUG to "files", "symbols" and/or "binding" and study the output. It reveals that libvtkCommonCore* is loaded, initialized and kept in memory all the time and before libA is loaded. When the linked tries to resolve "SymbolX" in libA, it does not search libvtkCommonCore, although it did for other libraries which needed the same symbol.
Note: I use Linux (Ubuntu 20) with the recent Gcc and CMake. Both the executable in situation 1 and "libC" in situation 2 were built with the flags "-Wl,--add-needed -Wl,--no-as-needed".
Note 2: if I launch the executable in situation 2 with LD_PRELOAD=libvtkCommonCore-custom1.so set, no errors appear.
I would be grateful for any hint how to continue debugging this issue.
A minimum example of the problem is comprised by these files:
libvtkCommonCore-custom1.cpp:
#include <iostream>
void SymbolX()
{
std::cout<<"This just does nothing useful."<<std::endl;
}
libA.cpp:
void SymbolX(); // in libvtkCommonCore-custom1.so
struct LibAStaticObject
{
LibAStaticObject()
{
SymbolX();
}
} libAStaticObject;
libB.cpp:
#include <dlfcn.h>
#include <iostream>
class LibALoader
{
public:
LibALoader()
{
void *handle = dlopen ( "libA.so", RTLD_LAZY|RTLD_GLOBAL|RTLD_NODELETE );
if ( !handle )
{
std::cerr<<"Could not load module library libA!\nReason: " << dlerror() << std::endl;
}
}
} libAloader;
libC.cpp
/*empty*/
executable_situation1.cpp:
#include <iostream>
int main(int argc, char*argv[])
{
std::cout<<"starting."<<std::endl;
return 0;
}
executable_situation2.cpp
#include <iostream>
#include <dlfcn.h>
class LibCLoader
{
public:
LibCLoader()
{
void *handle = dlopen ( "libC.so", RTLD_LAZY|RTLD_GLOBAL|RTLD_NODELETE );
if ( !handle )
{
std::cerr<<"Could not load module library libC.so!\nReason: " << dlerror() << std::endl;
}
}
} libCloader;
int main(int argc, char*argv[])
{
std::cout<<"starting."<<std::endl;
return 0;
}
CMakeLists.txt:
add_library(vtkCommonCore-custom1 SHARED libvtkCommonCore-custom1.cpp)
add_library(A SHARED libA.cpp)
add_library(B SHARED libB.cpp)
target_link_libraries(B dl)
add_library(C SHARED libC.cpp)
target_link_libraries(C vtkCommonCore-custom1 B)
set_target_properties(C PROPERTIES LINK_FLAGS "-Wl,--add-needed -Wl,--no-as-needed -Wl,--copy-dt-needed-entries")
add_executable(executable_situation1 executable_situation1.cpp)
target_link_libraries(executable_situation1 vtkCommonCore-custom1 B)
set_target_properties(executable_situation1 PROPERTIES LINK_FLAGS "-Wl,--add-needed -Wl,--no-as-needed -Wl,--copy-dt-needed-entries") #"-Wl,--no-as-needed")
add_executable(executable_situation2 executable_situation2.cpp)
target_link_libraries(executable_situation2 dl)
Run it by these commands:
$ mkdir build
$ cd build
$ cmake .. && make
$ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./executable_situation1
This just does nothing useful.
starting.
$ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./executable_situation2
./executable_situation2: symbol lookup error: ./libA.so: undefined symbol: _Z7SymbolXv
Indeed, the problem is that in situation 2 the libvtkCommonCore is not in the lookup scope of libA while in situation 1 it is in the global scope.
The only (probably ugly) solution I found was to put in a kind of a stub library that loads libvtkCommonCore along with libB using "dlopen" with option "RTLD_GLOBAL". This places libvtkCommonCore in the global lookup scope. The new library is then linked to libC instead of its direct dependencies.

Microsoft optimizing compiler 8.00 linker issue

#include<stdio.h>
void CopyBuffer(char *dest, char *src, int len)
{
memcpy(dest, src, len);
}
int main()
{
char *text = "Hello";
char buf[20];
CopyBuffer(buf, text, 6);
}
While using MSVC to compile above code I am facing couple of linking error saying
unresolved external
One example is if I use memcpy it is throwing error message
error L2029: '_memcpy' : unresolved external error L2029:
'__acrtused' : unresolved external error L2029: '__aNchkstk' :
unresolved external
Do I need to add library path during linking. But I have also observed if I use maximum optimization using /Ox _memcpy and __aNchkstk don't appear. Linker version is as it appear in console
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5
1994

Warning C4278: 'GetCurrentDirectory': identifier in type library 'GCRComp.tlb' is already a macro; use the 'rename' qualifier

I'm migrating a VC++ 6.0 application to Visual studio 2008. I've fixed all the migration errors, now I'm fixing the warnings. The following warning occurs in almost 40 instances, Even after so much trial and errors and research in google, I'm not able to fix this warning.
Please find below an instance of the C42778 Error, If I get some help to fix the one below, I'll follow the same approach to fix the remaning 39 warnings.
Warning C4278: 'GetCurrentDirectory': identifier in type library 'GCRComp.tlb' is already a macro; use the 'rename' qualifier
------Code snippet from ZipFile1.h -------
#import "GCRCOmp.tlb" rename_namespace("GCRTools") // C42778
------Code snippet from gcrcomp.tlh -------
Virtual HRESULT __stdcall raw_GetCurrentDirectory {
/*[out]*/ BSTR * dirname,
/*[out, retval]*/ VARIANT_BOOL * okStatus)=0;
virtual HRESULT __stdcall get_currentDirectory {
/*[out, retval]*/ BSTR * pVal)=0;
__declspec(property(get=GetcurrentDirectory))
_bstr_t currentDirectory;
VARIANT_BOOL GetCurrentDirectory (
BSTR * dirname);
_bstr_t GetcurrentDirectory ();
------Code snippet from gcrcomp.tli-------
inline VARIANT_BOOL IFtp1::GetCurrentDirectory(BSTR * dirname){
VARIANT_BOOL _result = 0;
HRESULT _hr = raw_GetCurrentDirectory(dirname, &_result);
if(FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
inline _bstr_t IFtp1::GetCurrentDirectory(){
BSTR _result = 0;
HRESULT _hr = get_currentDirectory(&_result);
if (FAILED(_hr) _com_issue_errorex(_hr, this, __uuidof(this));
return _bstr_t(result, false);
}
Any help to fix this warning is greatly appreciated. Thanks a lot in advance!
It because GetCurrentDirectory is already defined in Windows SDK. It is a part of ANSI/Unicode API conversion. The way to fix is undefined it before import GCRCOmp.tlb. Try this:
#pragma push_macro("GetCurrentDirectory")
#undef GetCurrentDirectory
#import "GCRCOmp.tlb" rename_namespace("GCRTools")
#pragma pop_macro("GetCurrentDirectory")

extern template DLLs and programs (crypto++)

I've been using Crypto++ with VS2005 and VS2010 for a while now. But recently I needed to use it with and application directly. The same code compiles fine when I'm compiling as a DLL and does not compile when compiling as an application.
This is the smallest sample that reproduces the error is this (based on cryptopp561\algparam.h:301 CryptoPP::AlgorithmParametersTemplate
class Base
{
protected:
virtual void MoveInto(void *p) const = 0;
};
template<class T>
class Test: public Base
{
public:
void MoveInto(void * buffer) const
{
Test<T> *x = new(buffer) Test<T>(*this);
}
};
extern template class Test<bool>;
The compilation parameters are the same, only difference that I saw was the configuration type in the project ("Application (.exe)" generates the error and "Dynamic Library (.dll)" does not).
This is the compiler error:
main.h(15): error C2061: syntax error : identifier 'buffer'
main.h(14) : while compiling class template member function 'void Test<T>::MoveInto(void *) const'
with
[
T=bool
]
main.h(20) : see reference to class template instantiation 'Test<T>' being compiled
with
[
T=bool
]
It seems to occur only when theres inheritance. Ommiting : public Base in the class Test declaration makes the error go away.
EDIT:
The problem was in a header included somewhere that defined a a debug version for operator new but didn't declared the placement new version.
Did you #include <new>, the header file that declares placement-new?
Funnily, extern templates are to tell the compiler to not instantiante at some point, so the second error does not make sense to me. Are you certain your compiler has support for extern templates? What if you do the opposite, explicit instantiation:
template class Test<bool>;

error C2065: 'CComQIPtr' : undeclared identifier

I'm still feeling my way around C++, and am a complete ATL newbie, so I apologize if this is a basic question. I'm starting with an existing VC++ executable project that has functionality I'd like to expose as an ActiveX object (while sharing as much of the source as possible between the two projects).
I've approached this by adding an ATL project to the solution in question, and in that project have referenced all the .h and .cpp files from the executable project, added all the appropriate references, and defined all the preprocessor macros. So far so good. But I'm getting a compiler error in one file (HideDesktop.cpp). The relevant parts look like this:
#include "stdafx.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WinInet.h> // Shell object uses INTERNET_MAX_URL_LENGTH (go figure)
#if _MSC_VER < 1400
#define _WIN32_IE 0x0400
#endif
#include <atlbase.h> // ATL smart pointers
#include <shlguid.h> // shell GUIDs
#include <shlobj.h> // IActiveDesktop
#include "stdhdrs.h"
struct __declspec(uuid("F490EB00-1240-11D1-9888-006097DEACF9")) IActiveDesktop;
#define PACKVERSION(major,minor) MAKELONG(minor,major)
static HRESULT EnableActiveDesktop(bool enable)
{
CoInitialize(NULL);
HRESULT hr;
CComQIPtr<IActiveDesktop, &IID_IActiveDesktop> pIActiveDesktop; // <- Problematic line (throws errors 2065 and 2275)
hr = pIActiveDesktop.CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER);
if (!SUCCEEDED(hr))
{
return hr;
}
COMPONENTSOPT opt;
opt.dwSize = sizeof(opt);
opt.fActiveDesktop = opt.fEnableComponents = enable;
hr = pIActiveDesktop->SetDesktopItemOptions(&opt, 0);
if (!SUCCEEDED(hr))
{
CoUninitialize();
// pIActiveDesktop->Release();
return hr;
}
hr = pIActiveDesktop->ApplyChanges(AD_APPLY_REFRESH);
CoUninitialize();
// pIActiveDesktop->Release();
return hr;
}
This code is throwing the following compiler errors:
error C2065: 'CComQIPtr' : undeclared identifier
error C2275: 'IActiveDesktop' : illegal use of this type as an expression
error C2065: 'pIActiveDesktop' : undeclared identifier
The two weird bits: (1) CComQIPtr is defined in atlcomcli.h, which is included in atlbase.h, which is included in HideDesktop.cpp; and (2) this file is only throwing these errors when it's referenced in my new ATL/AX project: it's not throwing them in the original executable project, even though they have basically the same preprocessor definitions. (The ATL AX project, naturally enough, defines _ATL_DLL, but I can't see where that would make a difference.)
My current workaround is to use a normal "dumb" pointer, like so:
IActiveDesktop *pIActiveDesktop;
HRESULT hr = ::CoCreateInstance(CLSID_ActiveDesktop,
NULL, // no outer unknown
CLSCTX_INPROC_SERVER,
IID_IActiveDesktop,
(void**)&pIActiveDesktop);
And that works, provided I remember to release it. But I'd rather be using the ATL smart stuff.
Any thoughts?
You may have forgotten the namespace ATL
ATL::CComQIPtr

Resources