Problems including jsonCpp headers - c++

I'm trying to implement the jsoncpp libraries in my C++ code, I wrote a simple piece of code just to try it out, and it's not even compiling.
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#ifndef json_included
#define json_included
#include "jsoncpp\include\json\json.h"
#endif
//#include "json\jsonC\json.h"
int main(int argc, char **argv)
{
std::string example = "{\"array\":[\"item1\", \"item2\"], \"not an array\":\"asdf\"}";
Json::Value value;
Json::Reader reader;
bool parsed = reader.parse(example, value, false);
std::cout << parsed;
return 0;
}
The errors i'm getting are:
undefined reference to `Json::Reader::parse(std::string const&, Json::Value&, bool)'
undefined reference to `Json::Reader::Reader()'
undefined reference to `Json::Value::~Value()'
undefined reference to `Json::Value::Value(Json::ValueType)'
I'm a bit new to C++, is there something I'm missing in the include statement? Or does jsonCpp need something extra?
Thank you for your time!

Your code is compiling, but it is not linking. You forgot to provide the JSON shared library files to your linker (or, on newer versions, to add the amalgamated jsoncpp.cpp to your project).
Without knowing more about your development environment, it's hard to give you more specific instructions.
BTW, you're writing C++; use C++ headers like cstdio, not stdio.h, please. You also failed to include C++ string and got lucky that it "worked" through some JSON header including it for you.

"Undefined reference" sounds like a linker problem. Does jsoncpp come with a library that you need to link to, such as a .so, .a, .lib or .dll file?
According to the jsoncpp README, the library must first be built using scons. Presumably this will then output a library file such as a .so, .a, .lib or .dll file. You must then follow your compiler's rule for linking against such a library (e.g. add it to the end of the command line when compiling, or add it to the "additional libraries" field in the project config in your IDE).

In my case (using CodeBlocks IDE on Ubuntu) the problem was that I needed to add the json.cpp file (generated with python amalgamate.py from within the jsoncpp project) to my build targets.
In other words, I added a -c jsoncpp.cpp option to my g++ compile statement.

You need to link to the json libraries, e.g. using -ljson_linux-gcc-4.4.3_libmt
You can find the exact library name by looking in the library directory, e.g. /usr/lib
If you're using Visual Studio, add the .lib file to Project Properties, Linker, Input, Additional Dependencies and specify the path in Project Properties, Linker, General, Additional Library Directories

Two potential issues:
There is a bug in some versions of the jsoncpp library code where amalgated needs to become amalgamation for the linking to work correctly.
As the other answers suggested, #include

After you compile jsoncpp you can find the libraries in the folder libs/ . For convenience you can put it in /usr/lib and then link it at run time by passing -llibjson_linux-gcc-4.4.3_libmt as an argument to g++.
I have renamed libjson_linux-gcc-4.4.3_libmt.so to libjson.so and can link it by specifying -ljson.

Related

Trouble including third-party code in my C++ application

I'm trying to include some networking code into my C++ application. I downloaded CSimpleSocket and I copied all the .h and .cpp files into the directory where my main file is. Then I tried including one of the headers, but the linker just barfs up a bunch of errors, like:
[Linker error] undefined reference to CPassiveSocket::CPassiveSocket(CSimpleSocket::CSocketType)'
[Linker error] undefined reference to `CSimpleSocket::Initialize()'
[Linker error] undefined reference to `CPassiveSocket::Listen(unsigned char const*, short, int)'
[Linker error] undefined reference to `CPassiveSocket::Accept()'
and others. Everything is in one directory, so I don't think that's the problem. The code I'm using to include is #include "PassiveSocket.h". I'm using Dev-C++, if that makes any difference. I don't understand what I'm doing wrong, so if somebody could help me, that would be great.
Forgive me if this is a really dumb question, but I'm trying to learn C++, and it's not easy. Thanks for your help.
The reason you're getting this error is because your compiler can't find the binary that corresponds to the CSimpleSocket headers. It's as if you wrote
void someFunction(int someArg);
And then never provided the implementation for someFunction.
To use a third party library you need two things:
Header files (.h, .hpp, etc...)
Library files (.a, .lib, etc...)
Once you've got your header files and library files you need to put them in a place your compiler can find them. This place will vary depending on your OS, environment variables and compiler configuration.
Now that they're somewhere the compiler can find them you need to tell the compiler to use them. Header files are used with the #include command and library files are linked by providing arguments to the compiler.
Behind the scenes Dev-C++ uses the MinGW GNU GCC compiler, it invokes a command similar to g++ file1.cpp file2.cpp ... filen.cpp -o filename that tells the program g++ to compile a C++ executable named "filename" using files 1 to n. There are other flags that can be added to g++ such as telling it where to search and what to link.
The name of the CSimpleSocket library when compiled is "clsocket" so we need to find a way to configure Dev-C++ to add -lclsocket to the g++ command. I don't use Dev-C++ so I can't help you here but you're probably looking for "Linking Options" or something similar in your compile configuration. You also need to make sure the .lib and .h files are on the search path which should also be configurable in Dev-C++.
CSimpleSocket also provides an installer that should automatically create the .lib file and place the .lib and .h in places where they can be found, you should consider using that installer.
I think the complexity of this answer highlights the abysmal state of the C++ library integration ecosystem. Unfortunately there is no concept of a "module" in C++ at the time of writing.

undefined reference to '_WSAStartup#8'. How to link libraries with NetBeans?

I use NetBeans, Windows and Cygwin with G++ compiler.
I'm examining Windows Sockets 2. I do everything that is written in MS manual. I have a code (mostly from this manual):
#include <winsock2.h>
#include <ws2tcpip.h>
#include <cstdlib>
#include <iostream>
#pragma comment(lib, "Ws2_32.lib")
int main() {
WSADATA wsaData;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
else cout << "Initialization OK.";
return 0;
}
And I have a problem when I try to run the project:
undefined reference to `_WSAStartup#8'
I understand that Ws2_32.lib is missing. This is because I do not have Windows SDK installed. But before installing it I want to try out tools that Cygwin offers. It has all the w32api header files, I have them in:
C:\cygwin\usr\include\w32api
And it has some w32api almost .lib files in the directory:
C:\cygwin\lib\w32api
But all these lib files are different, they have .a extension and a little bit different name, like:
libws2_32.a // in Cygwin
vs.
ws2_32.lib // in Windows
When I use Cygwin terminal to create an .exe file, everything works fine. The commands I input are:
cd C:\\c++\\myProgram // go to the dir
g++ myProgram.cpp -lws2_32 // compile using -l option to link libws2_32.a
And after it I get a.exe file. I run it and it works:
./a.exe // Initialization OK.
But as I said I use NetBeans. And if I try to run the project from NB ([F6] button) I always have this error undefined reference to '_WSAStartup#8'.
I've tried already everything I could find on NB forums. I've tried to link libws2_32.a to my project this way. I go to:
File -> Project Properties -> Linker -> Libraries
And there are three options:
Add Library...
Add Library File...
Add Option...
I've tried them all. I've tried to link both just Add Library... and Add Library File.... I've also tried to add such an option in the Add Option... button:
Add Option... -> Other option -> // and I input here "-lws2_32"
But whatever I do I can't run the project from NB, I get error undefined reference to '_WSAStartup#8'.
So it seems that it is not a problem (error) in the code. It seems that the problem is with NB, with its possibility to link libraries. Or I do wrong steps to attach them to the project.
So my questions are:
1) What do I do wrong? How may I run the project right from NB? I didn't try to install Windows SDK, I want to try with Cygwin tools as it has such kind of tools.
2) What is the difference between Windows .lib files and Cygwin .a files? Is it better to install Windows SDK and just forget about those .a files? Everything I could find so far about them on Cygwin site is this:
The import library is a regular UNIX-like .a library, but it only
contains the tiny bit of information needed to tell the OS how your
program interacts with ("imports") the dll. This information is linked
into your .exe. This is also generated by dlltool.
3) Is it possible to use #pragma comment(lib, "libws2_32.a") to link .a files? I've tried but didn't get success results.
1) What do I do wrong? How may I run the project right from NB? I didn't try to install Windows SDK, I want to try with Cygwin tools as it has such kind of tools.
Try this: http://forums.netbeans.org/ptopic44959.html
2) What is the difference between Windows .lib files and Cygwin .a files? Is it better to install Windows SDK and just forget about those .a files?
Both of these files in this particular case are called "import libraries". Import libraries are basically a file containing a list of valid functions, so that when you link your exe, the linker knows that those functions will exist in some particular DLL. So when you link to wsock32.lib or ws2_32.lib, the linker now knows that these functions will exist in wsock32.dll and ws2_32.dll. Thus, it will not complain. Now, the .lib import library format is Microsoft's format. GCC/unix/linux/mingw/cygwin etc. have a different format, and the extension for that format is .a. Now, cygwin/mingw etc. provide a ws2_32.a so that when using cygwin/mingw/gcc, the linker can read the import library in the correct format. cygwin/mingw/gcc will simply not understand the .lib. Microsoft provides the .lib files in their SDK, but I am not sure how this will help in this case. (Though the SDK is definitely useful, because it provides lots of header files and DLLs for other useful things you might need, but the import libraries are useless, because gcc/mingw/cygwin will not understand them; unless you use a converter tool, like the one mentioned in your duplicate question).
3) Is it possible to use #pragma comment(lib, "libws2_32.a") to link .a files? I've tried but didn't get success results.
No, the #pragma linking comments are an MSVC specific (ugly IMO) extension. Use the linker options in the menus.
eclipse, Cygwin
propeties -> C/C++ Build -> Settings -> Cygwin C Linker
Command line pattern
add to -lws2_32
ex)${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} -lws2_32

undefined reference errors after running cmake

I've tried to essentially build the PhysFS library with Cmake, what I used was Code::Blocks mingw makefiles. I can import in my project, I can technically declare the PhysFS_init() function (although that gives me too few arguments error) yet when I add an argument it tells me PHYSFS_init is an undefined reference.
That sounds so silly to me, how can you recognize it when it has no argument, but pretend it doesn't exist when I add an argument? I've run CMake twice, but I'm simply getting this:
[...]\src\main.cpp|20|undefined reference to `PHYSFS_init'|
The code, if necessary (just a bit, the rest is irrelevant):
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include "Globals.h"
#include "GameStates.h"
#include "GameWindow.h"
#include "GameMenu.h"
#include <physfs.h>
int main(int argc, char** argv)
{
///<|===================| Classes & Declarations |===================|>
sf::Event ev;
sf::RenderWindow winMain ( sf::VideoMode( WindowWidth, WindowHeight, 32 ), WindowTitle );
sf::Image Icon;
GameStates gameState;
GameMenu TitleMenu;
MenuButton buttons[4];
PHYSFS_init(NULL);
Why is this happening? What do I have to do to be able to use PhysFS in my project? I've built the library with CMake, I included the library I need, and I tried to initialize PhysFS which gave me an error which makes me feel like the way C++ compiles program is plain silly.
This is a general explanation of how C++ libraries work:
PHYSFS probably consists of header files and a static/dynamic library. The header file is where all the functions/classes of the library are declared, but not defined. Thus, when you include the header file into your project, your compiler can now know that the functions you call in the library exist, and exactly what type of parameters they take etc.
So to use a library, you must include its header files, which means you must add its include directory to the project/cmakelists.txt.
#some similar path to this
include_directories( /path/to/PHYSFS/include)
Now, when you actually link the executable into a binary, these functions must be "resolved" so that the linker knows where they actually are, so that they can be called. This is called "linking" with the library.
So to use a library you must link its library files.
In cmake this is done as follows:
add_executable(myexe myexe.cpp)
#Add library directory paths here
link_directories( /path/to/PHYSFSlibs/)
#libPHYS.a or libPHYS.so if using gcc convention, libPHYS.lib if MSVC convention
#cmake allows us to use the name of the library, instead of the filename to be portable.
target_link_libraries(myexe PHYSFS)
I am not particularly familiar with PHYSFS, but if you compiled it as a library, you should have one of these files to link to.
undefined reference to `PHYSFS_init
This is a problem with "linking" and usually means you failed to link the library, or the library is missing the implementation of this function. Linking the library should fix this.
EDIT
I misread your question, and assumed you were using cmake with your project and linking to PHYSFS.
First you must separately build PHYSFS, which will produce a library file (.a,.so or .lib) depending on the platform/IDE, then you must link that library file in your C::B linker options.
To do this:
Go to Project->Build options. Click Linker Settings.
Image (from here):
Add the library.

C++ include libraries

Ok, so it's been a while, and i'm having problems with #includes
So I'm doing
#include "someheader.h"
but it's giving me
fatal error: someheader.h: No such file or directory
It's a system wide library I guess you could say.
I'm running arch linux and I installed the library from the repo, and I think the .h files are in /usr/include.
I could just copy all the header files into the folder my code is in but that would be a hack.
What is the "right" way to do this?
Edit: I wasn't correct by saying the .h files were in /usr/include, what I meant was that the library folder was in there
So, Emile Cormier's answer worked to a certain extent.
The problem now is that there are some include in the header file and it seems from the methods I'm trying to access that those includes are not happening
it's giving my the error
undefined reference to Namespace::Class::method()
Edit:
Ok so the final answer is:
#include <library_name/someheader.h>
And compile with
g++ code.cpp -llibrary_name
Sometimes, header files for a library are installed in /usr/include/library_name, so you have to include like this:
#include <library_name/someheader.h>
Use your file manager (or console commands) to locate the header file on your system and see if you should prefix the header's filename with a directory name.
The undefined reference error you're getting is a linker error. You're getting this error because you're not linking in libsynaptics along with your program, thus the linker cannot find the "implementation" of the libsynaptics functions you're using.
If you're compiling from the command-line with GCC, you must add the -lsynaptics option to link in the libsynaptics library. If you're using an IDE, you must find the place where you can specify libraries to link to and add synaptics. If you're using a makefile, you have to modify your list of linker flags so that it adds -lsynaptics.
Also the -L <path_to_library> flag for the search path needs to be added, so the linker can find the library, unless it's installed in one of the standard linker search paths.
See this tutorial on linking to libraries with GCC.
You'd use #include <someheader.h> for header files in system locations.
#include "someheader.h" would try to include the file someheader.h in the directory of your .c file.
In addition to including the header file, you also need to link in the library, which is done with the -l argument:
g++ -Wall youprogram.cpp -lname_of_library
Not doing so is the reason for the "undefined reference .. " linker errors.
The quick fix is to do use:
#include <someheader.h>
assuming that someheader.h is in the standard include locations (to find it use the command locate someheader.h in a shell. If it is in /usr/include it is in a standard location. If it is in a subdirectory of /usr/include you only need to add the part of the directory up to /usr/include in the #include directive (e.g. #include <fancy_lib/someheader.h>)
However, this is only half of the story. You also will need to set up your build system in a way that locates the given library and adds its include path (the path under which it's header files are stored) to the compiler command (for gcc that is -I/path/to/header). That way you can also build with different versions by configuring them in your build system. If the library is not header-only you will also have to add it to the linker dependencies. How this is achieved in your build system is best found out by consulting its documentation.

C/C++ ftplib: Undefined reference to _imp__FtpInit

I am trying to use a C/C++ FTP library (>here's the website). When I try to call the FtpInit() function I get a compilation error telling me that there is an undefined reference to _imp__FtpInit. This is what I'm trying to compile:
#include "ftplib/ftplib.h"
int main()
{
FtpInit();
return 0;
}
Did you remember to set your -L library path to the location where you installed the library, and use -lftplib (or similar depending on the actual library file's name) to link the library?
For Visual Studio, add the .lib file to the "Additional Dependencies" setting in project properties/Linker/Input.
You may also need to set "Additional Library Directories" in Project Properties/Linker/General