#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
Related
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.
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
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>;
I'm trying to link my app with the Maya C++ API, but i get:
Debug/../src/main.cpp:80: undefined reference to `MLibrary::initialize(bool, char*, bool)'
but, nm shows:
nm libOpenMayalib.a | grep initialize
00000000000004b0 T _ZN8MLibrary10initializeEPcb
0000000000000380 T _ZN8MLibrary10initializeEbPcb
0000000000000000 b _ZZN8MLibrary10initializeEbPcbE13isInitialized
which seems to match MLibrary::initialize, that looks like:
class OPENMAYA_EXPORT MLibrary
{
public:
MLibrary ();
virtual ~MLibrary ();
static MStatus initialize (char* applicationName,
bool viewLicense = false);
static MStatus initialize (bool wantScriptOutput,
char* applicationName,
bool viewLicense = false);
static void cleanup( int exitStatus = 0 );
protected:
// No protected members
private:
// No private members
};
The linking process is run with:
g++ -L/usr/autodesk/maya2009-x64/lib -m64 -pthread -Wl,-rpath,/usr/autodesk/maya2009-x64/lib -lOpenMayalib -l3dGraphics -lAG -lAnimEngine -lAnimSlice -lAnimUISlice -lAppVersion -lAshliFX -lAshli -lAutoCam -lawCacheShared -lawnSolver -lawxml2 -lBase -lCgGL -lCg -lCloth -lCommandEngine -lcxaguard -lDataModel -lDebug -lDeformSlice -lDeformUISlice -lDependCommand -lDependEngine -lDevices -lDynSlice -lDynUISlice -lExplorerSlice -lExtensionLayer -lfbxfilesdk -lFoundation -lgcc_s -lGeometryEngine -lguide -lhairlib -lHalf -lHumanIKShared -lHWFoundation -lHWGL -lHWRenderMaya -lHWRender -lIex -liff -lIlmImf -lImage -lImageUI -lImath -lIMFbase -limf -lirc -lJasperSlice -lKinSlice -lKinUISlice -lManips -lMaya -lmocap -lModelSlice -lModelUISlice -lModifiers -lMotionCapture -lNurbsEngine -lNurbsSlice -lNurbs -lNurbsUISlice -lOpenMayaAnim -lOpenMayaFX -lOpenMayaRender -lOpenMaya -lOpenMayaUI -lPolyEngine -lPolySlice -lPoly -lPolyUISlice -lProjectSlice -lPsdTexture -lpython2.5 -lRenderModel -lRenderSlice -lRenderUISlice -lShared -lSharedUI -lstdc++ -lstdc++ -lSubdivEngine -lSubdivGeom -lSubdiv -lSubdivUI -lsvml -ltbbmalloc -ltbb -lTranslators -lUIComponents -lUrchinSlice -lUrchinUISlice -lXm -lzlib -o"BinaryGL3MdlMayaExporter" ./src/Exporter.o ./src/Format.o ./src/Generic.o ./src/Output.o ./src/main.o -lm -lgtk-x11-2.0 -ldl -lpthread -lgdk-x11-2.0
The system is Ubuntu Maverick 10.10, 64-bit, and Maya is 64-bit as well, and compiling with -m64 gives the same result.
I found a similar post http://area.autodesk.com/forum/autodesk-maya/sdk/link-errors-when-using-the-openmaya-api-on-linux/ i took some ideas from his file, like using the -Wl,-rpath, but, that doesn't change anything..
I also tried installing g++-4.1 as it seems to be the one mentioned in the scripts, but that didn't change anything either (current version is g++-4.4)
Thanks in regards
//Johan
The problem is the way you call MLibrary::initialize.
It expects a non-const char string, which is probably fed with a literal char string that is implicitly constant.
What you call is something like lib.initialize(false, "my app", false) which equals MLibrary::initialize(bool, const char*, bool) - this signature is indeed not exported by MLibrary.
What you have to do to make it work is to use a non-const application name, for example:
// char* appName = "my app"; would be deprecated as string literals are always const
char appName[] = {'m','y',' ','a','p','p'};
lib.initialize(false, appName, false);
Note: This is an interface bug as the application name should indeed be fed as a const char* - this bug is fixed in later maya versions.
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