Linking to ARPACK from VS2010 - c++

I am trying to get the ARPACK library to run on VS2010.
I would like to use the C++ wrappers
provided by ARPACK++ (some background - i need to get eigenvalues and eigenvectors of huge matrices). There is a very good tutorial on the subject here.
Following the
tutorial i've managed to compile the fortran code using g77 on mingw, i successfully generated
the dll and lib as described. The problem arises when trying to link my visual studio project to the library.
The way i'm trying to link is as follows:
I've made a simple VS2010 C++ console app
i've added the the folder containing ARPACK++ libraries to my "additional include folders"
i've added the lib file to "Additional dependencies"
i've added the directory containg the lib file to my "Additional library directories"
Despite these settings when i try to compile this short test code:
#include "stdafx.h"
#include "arrsnsym.h"
int _tmain(int argc, _TCHAR* argv[])
{
ARrcNonSymStdEig<float> prob(100, 4L);
printf("Bok!");
return 0;
}
I get an error saying:
>arpackcpp.obj : error LNK2001: unresolved external symbol scopy_
1>arpackcpp.obj : error LNK2001: unresolved external symbol snaupd_
1>arpackcpp.obj : error LNK2001: unresolved external symbol sneupd_
I do not understand why the linker can't find the mentioned methods. Inspecting
the .def file generated by the dllwrap utility does indeed mention all these functions
so i am fairly sure they should be available. Still, i feel i'm missing something obvious.
UPDATE (got it working!):
It turns out that i was trying to link a 64 bit program to a 32 bit library, when switching
to x86 in the Configuration settings AND including the generated def file in Configuration Properties -> Linker -> Input -> Additional definition file, it worked for 32bit (however i needed 64). The final solution that worked for me was to cross compile it for Win64 using MinGW and gfortran on linux. That worked surprisingly well and produced a dll to which i could link from a 64bit C++ app in VS. I think i should now go write a tutorial on how to do this :)

My guess is that this is a name-mangling scheme issue. In fortran, it is not well defined what name the symbols will have in the object file's symbol table. For example, a routine named foo could end up in the symbol table as foo,FOO,foo_,foo__ and so on. These days, I don't know of too many compilers that use double underscores (with g77 being the exception). I'm assuming the ARPACK++ wrappers are assuming a single underscore. The solution here is to tell the compiler to use single underscores in the symbol names (with g77, that means using -fno-second-underscore). Note that gfortran is a newer (still supported) open-source fortran compiler which does single underscoring by default. You might want to try to build your code using that compiler as well. (It might produce more optimized output than g77.)

Related

Integrating ImageMagick:x64-windows-static library in VS2019 project

I am trying to create a VS2019 project with ImageMagick (Magick++) as a statically linked library.
I have followed the directions from https://github.com/ImageMagick/ImageMagick-Windows.
In the wizard configurator I requested:
Build Type: Static Multi-threaded runtimes
Kept most settings to the default beyond that.
In my project I have set the header file include path to include:
C:\developer\ImageMagick\ImageMagick\
C:\developer\ImageMagick\ImageMagick\Magick++\lib
I have added library paths of:
C:\developer\ImageMagick\VisualMagick\lib
and I have added the relevant 3 library files for debug and release.. debug shown below:
CORE_DB_Magick++_.lib
CORE_DB_MagickCore_.lib
CORE_DB_MagickWand_.lib
In code I have:
#include <Magick++.h>
...
char szImageMagickLIBDirectory[MAX_PATH];
strcpy_s(szImageMagickLIBDirectory, MAX_PATH, "C:\\developer\\ImageMagick\\VisualMagick\\lib");
Magick::InitializeMagick(szImageMagickLIBDirectory);
Unortunately I get many LNK2001 unresolved external symbol errors during linking.
example:
LNK2001 unresolved external symbol UnregisterGRADIENTImage <myProjectName> <my_project_path>\CORE_DB_Magick++_.lib(static.obj) 1
Does anyone have information on how to setup a VS project for ImageMagick:x64-windows-static library use?
My backup plan (as you may deduce from my vcpkg notation) will be to use GraphicsMagick.
Well I feel a right idiot!
My mistake was thinking that the all the additional LIBs had been compiled into the 3 key LIBs commonly referenced and used by ImageMagick. That simply isnt the case! Gah! The very simple answer is to add all thirty odd static libraries to the project! Thats all!
I honestly thought I was dealing with some complex Linker settings issue, when the problem was simply my arrogant assumption!
I must now consume coffee to stave off the mind altering dumbness I feel!

Unresolved external symbol error while using CImg library

I am trying to use CImg library for some image processing task. Using VS 2012 on Windows 7 x64, I am building a project to create dll that I need for my application. I have included the only header file CImg.h from the library. But as soon as I initialize an CImg object, I get bunch of unresolved external symbol errors. One sample error is as follows:
layer.obj : error LNK2019: unresolved external symbol __imp_SetDIBitsToDevice referenced in function "public: struct cimg_library::CImgDisplay & __cdecl cimg_library::CImgDisplay::paint(void)" (?paint#CImgDisplay#cimg_library##QEAAAEAU12#XZ)
Can anyone explain to me what am I doing wrong and how to fix it? (I am a newbie when it comes to C++ terminologies.)
there is nothing other than the header file in the CImg library to link to.
You cannot link to a header file. If it is a header-only library, then you do not need to link anything. You include the header file and the functions it defines are compiled directly. That appears to be the case for CImg; the documentation says it is a self-contained template library that consists of only a single header file. So indeed, all you need to do is include it and you're off to the races.
The unresolved external symbol errors are coming from somewhere else. You have to read the error messages and look at the function names to see where.
A couple of hints:
The __imp_ prefix suggests that you're looking at a Windows API function.
If you didn't know that, you could always ignore the prefix and Google the readable part of the name, in this case, SetDIBitsToDevice. Chances are very good you'll turn up the documentation or at least something that points you in the right direction.
Indeed, in this case, you get right to Microsoft's SDK documentation for the SetDIBitsToDevice function. It's a Windows API function alright, and Microsoft's documentation always tells you what library you need to link to in order to consume it. Look at the bottom of the page:
Header: Wingdi.h (include Windows.h)
Library: Gdi32.lib
DLL: Gdi32.dll
The CImg library header file has obviously already included the Windows.h header file, or you'd have gotten a compile-time error. You're getting a linker error, which means that you have not told the linker to link in the Gdi32.lib library. This is what will allow you to call GDI functions. It is a stub that facilitates calling functions exported from Gdi32.dll.
In general, when building a Windows application, you will want to link with, at minimum, kernel32.lib, user32.lib, and gdi32.lib.
This question contains more information on dealing with undefined symbol errors, and also how to configure your linker. In Visual Studio, go to Project Properties → C/C++ → Linker → Input → Additional Dependencies. Or add #pragma comment(lib, "gdi32.lib") to a source file (your precompiled header is a good place, usually named StdAfx.h).
This function is part of the win32 API, specifically in GDI. You need to change your project settings to link with Gdi32.lib
https://msdn.microsoft.com/en-us/library/windows/desktop/dd162974(v=vs.85).aspx

Unresolved external symbol linking to a VS6 library

I've got an NIUSB8452 DAQ, with which the vendor thoughtfully provided ni845x.lib and ni845x.h so I could use C instead of LabView to do my data reading. However, I'm having some problems with getting the lib working in VisualStudio 2015. The first point of alarm is probably that their documentation says it is compatible with VS6, but I've seen other people on here successfully use libraries for VS6 on VS15, so, I hope I can also be so beautiful.
The problem that I am having right now is that on a build, I'm getting linker errors that read something like
unresolved external symbol #ni845xStatusToString#12 referenced in function (function name follows)
While googling around, I found this question which mentioned dumpbin /exports. To check that I wasn't running into a 32/64 bit error like the poster described (since I wasn't really sure how to diagnose this, it seemed as good a place to start as any), I ran dumpbin /exports on the external lib. I got a pile of public symbols, including
FF06 __imp__ni845xStatusToString#12
FF06 _ni845xStatusToString#12
I'm definitely not seeing #ni845xStatusToString#12, which is what VisualStudio is complaining about being unresolved.
What's the difference between #ni845xStatusToString#12 and _ni845xStatusToString12? What does the presence of the latter and the absence of the former indicate that I am doing wrong with this import?
Notes
The lib and header have been included in the file as described in this question, with the exception that I gave a full path to the lib for #4, which I think implies you only need the filename.
I'm using extern "C" { #include ni845x.h } in my cpp file, although ni845x.h does have the #ifdef __cplusplus boilerplate in there.

Mysterious "unresolved symbols" linker errors when compiling against large static lib

I am receiving a lot of strange LNK2001 and LNK2019 errors when attempting to compile and link against a somewhat large static library (developed in-house). Here are the facts:
There are several static libs (most built in-house) all compiled into one large wrapper static lib for public consumption ("Pimpl" idiom). Essentially, we have libs A, B, and C all compiled into an internal/private lib called D. Then, we have an external/public lib that wraps around D called E.
The final product is not an executable, but a plug-in for Adobe Illustrator. Plug-ins are essentially just a DLL with a couple special resources and a special entry point (PluginMain() function). Compiling and linking works just great until I use the /INCLUDE option to specify that PluginMain should always be exported.
Creating a plug-in and linking against lib D works fine (no errors whatsoever). Creating a plug-in and linking against lib E gives over 100 unresolved symbol errors (symbols that should be present in E).
When I run DUMPBIN on the E.lib file, it appears to have all the symbols that the linker is complaining about when trying to create a plug-in. However, I'm not entirely certain I understand all the output syntax from DUMPBIN...
The libs are all cross-platform and compile and link just fine with GCC/LLVM on Mac.
Most of the functions that the linker complains about are either plain functions or static member functions. Most of those look suspiciously like functions that the compiler might try to inline. I have tried disabling optimization and/or automatic inlining, but the same link errors are still present.
Can anyone point me in the direction of some compile and/or link settings that might resolve the issue? Settings that are commonly misconfigured in situations like this?
Perhaps there is a setting I missed that is causing the linker not to export these symbols when linking E? Perhaps there is a setting that forces the linker to export ALL symbols when linking E that I can try? Maybe a utility exists to help me inspect the lib symbols myself for a clue?
I feel like I've tried everything, but it never hurts to ask. Thanks all.
EDIT 1: snowdude requested an actual link error:
E.lib(PathArt.cpp.obj) : error LNK2001: unresolved external symbol "private: __thiscall E::PathSegPoint::PathSegPoint(struct D::PathSegPoint const &)" (??0PathSegPoint#E##AAE#ABU0D###Z)
I should add that E::PathSegPoint::PathSegPoint(const D::PathSegPoint&) is a private constructor for constructing an external/public consumable E::PathSegPoint object from an internal/private D::PathSegPoint object. Again, this is the "Pimpl" idiom. Some classes/functions are friends of E::PathSegPoint to enable this sort of construction.
I thought I'd post an answer in case anyone shows up to this page in the future.
For several reasons a few years ago, we started compiling these libraries with the Intel C++ compiler inside Visual Studio. Some of these reasons have changed, and we needed to switch back to the MSVC compiler. Upon switching to the MSVC compiler, these linker errors disappeared!
I don't know why or how the Intel C++ compiler developed these link problems, but it's entirely possible that this is a bug.

Getting FreeImage to work with Visual Studio 2010

I was advised by some of you not to long ago to use FreeImage as a library for image processing in C++.
I now have some trouble in getting the library to work (still relatively new here).
I've tried loading the various vcxproj and sln tiles and they gave me a blank project. Since there isn't any installation instructions provided for that, I gave up on making it a visual studio solution.
I next tried the old-fashion way of compiling the source code using the Makefile and then adding "FreeImage/Source" to the linker. While the IDE does not raise any red flags when I call functions declared in FreeImage.h, it gave me a bunch of "error LNK2019: unresolved external symbol" during compilation, as if the functions do not exist. What I suspect is that the IDE could not find the .cpp files that define the said functions, but I still get that same problem when I added FreeImage/Source/FreeImage to the linker.
Now when I directly included some of the .cpp files (i.e. Plugin.cpp and FreeImage.cpp) for a test, I get even more unresolved external symbol errors as well as things like "inconsistent dll linkage" for this within... for example FreeImage.cpp:
const char * DLL_CALLCONV
FreeImage_GetVersion() {
static char s_version[16];
sprintf(s_version, "%d.%d.%d", FREEIMAGE_MAJOR_VERSION, FREEIMAGE_MINOR_VERSION, FREEIMAGE_RELEASE_SERIAL);
return s_version;
}
So, I am totally stuck. What am I doing wrong? I felt I've followed the adequate steps in adding library dependencies, such as adding the specific folders that are immediate parents to the relevant .h and .cpp files in C/C++ -> General -> Additional Included Directories and Linker -> General -> Addition Library Directories.
Some help will be greatly appreciated!
Using FreeImage v3.15.3 I had no problems converting the VS2008 project to VS2010.
Also the building worked as expected. But when I linked to the static lib, I got some unresolved externals. First I tried al kinds of tricks setting /MT /MD linking, but that did not solve these linking problem.
After reading Some Newbie's comment I dug into freeimage.h. There I found a macro switch FREEIMAGE_LIB that controls the calling conventions of the function.
Use a #define FREEIMAGE_LIB before including the freeimage.h file. That way you can easily static link to FreeImage.lib