Can not link to pcl library. - linker

The following code:
#include <ros/ros.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <boost/foreach.hpp>
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
void callback(const PointCloud::ConstPtr& msg)
{
printf ("Cloud: width = %d, height = %d\n", msg->width, msg->height);
BOOST_FOREACH (const pcl::PointXYZ& pt, msg->points)
printf ("\t(%f, %f, %f)\n", pt.x, pt.y, pt.z);
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "sub_pcl");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe<PointCloud>("points2", 1, callback);
ros::spin();
}
Which is a default example taken from here
My CMake:
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
find_package(PCL 1.3 REQUIRED COMPONENTS common io)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
target_link_libraries(${PROJECT_NAME} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES})
Which is the exact configuration recommended on the pcl official website
I still get the following linking error:
CMakeFiles/apsp_manifold.dir/src/apsp_manifold.cpp.o: In function `void pcl::detail::FieldMapper<pcl::PointXYZ>::operator()<pcl::fields::z>()':
/usr/include/pcl-1.7/pcl/conversions.h:106: undefined reference to `pcl::console::print(pcl::console::VERBOSITY_LEVEL, char const*, ...)'
CMakeFiles/apsp_manifold.dir/src/apsp_manifold.cpp.o: In function `void pcl::detail::FieldMapper<pcl::PointXYZ>::operator()<pcl::fields::y>()':
/usr/include/pcl-1.7/pcl/conversions.h:106: undefined reference to `pcl::console::print(pcl::console::VERBOSITY_LEVEL, char const*, ...)'
CMakeFiles/apsp_manifold.dir/src/apsp_manifold.cpp.o: In function `void pcl::detail::FieldMapper<pcl::PointXYZ>::operator()<pcl::fields::x>()':
/usr/include/pcl-1.7/pcl/conversions.h:106: undefined reference to `pcl::console::print(pcl::console::VERBOSITY_LEVEL, char const*, ...)'
What do I have the above described error and how can I remove it?

Just a guess, but maybe the problem is that not all required components are included.
This is how I link PCL:
find_package(PCL REQUIRED)
include_directories( ... ${PCL_INCLUDE_DIRS})
...
target_link_libraries( ... ${PCL_LIBRARIES})

The problem was as follow: the code from the tutorial was old, the last time the page was modified - 2011-08-09.
The only reasonable explanation I could find is that apparently the PCL library did not remove from the headers the code related to older versions, but removed only the symbol files related to those function calls, so what would happen is: the parsing would succeed (as the function declarations are there) while the linking would fail since there is nothing to link. This is the tutorial I ended up using.

Related

Check if a system implements a function

I'm creating a cross-system application. It uses, for example, the function itoa, which is implemented on some systems but not all. If I simply provide my own itoa implementation:
header.h:115:13: error: conflicting types for 'itoa'
extern void itoa(int, char[]);
In file included from header.h:2:0,
from file.c:2:0,
c:\path\to\mingw\include\stdlib.h:631:40: note: previous declaration of 'itoa' was here
_CRTIMP __cdecl __MINGW_NOTHROW char* itoa (int, char*, int);
I know I can check if macros are predefined and define them if not:
#ifndef _SOME_MACRO
#define _SOME_MACRO 45
#endif
Is there a way to check if a C function is pre-implemented, and if not, implement it? Or to simply un-implement a function?
Given you have already written your own implementation of itoa(), I would recommend that you rename it and use it everywhere. At least you are sure you will get the same behavior on all platforms, and avoid the linking issue.
Don't forget to explain your choice in the comments of your code...
I assume you are using GCC, as I can see MinGW in your path... there's one way the GNU linker can take care of this for you. So you don't know whether there is an itoa implementation or not. Try this:
Create a new file (without any headers) called my_itoa.c:
char *itoa (int, char *, int);
char *my_itoa (int a, char *b, int c)
{
return itoa(a, b, c);
}
Now create another file, impl_itoa.c. Here, write the implementation of itoa but add a weak alias:
char* __attribute__ ((weak)) itoa(int a, char *b, int c)
{
// implementation here
}
Compile all of the files, with impl_itoa.c at the end.
This way, if itoa is not available in the standard library, this one will be linked. You can be confident about it compiling whether or not it's available.
Ajay Brahmakshatriya's suggestion is a good one, but unfortunately MinGW doesn't support weak definition last I checked (see https://groups.google.com/forum/#!topic/mingwusers/44B4QMPo8lQ, for instance).
However, I believe weak references do work in MinGW. Take this minimal example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
__attribute__ ((weak)) char* itoa (int, char*, int);
char* my_itoa (int a, char* b, int c)
{
if(itoa != NULL) {
return itoa(a, b, c);
} else {
// toy implementation for demo purposes
// replace with your own implementation
strcpy(b, "no itoa");
return b;
}
}
int main()
{
char *str = malloc((sizeof(int)*3+1));
my_itoa(10, str, 10);
printf("str: %s\n", str);
return 0;
}
If the system provides an itoa implementation, that should be used and the output would be
str: 10
Otherwise, you'll get
str: no itoa
There are two really important related points worth making here along the "don't do it like this" lines:
Don't use atoi because it's not safe.
Don't use atoi because it's not a standard function, and there are good standard functions (such as snprintf) which are available to do what you want.
But, putting all this aside for one moment, I want to introduce you to autoconf, part of the GNU build system. autoconf is part of a very comprehensive, very portable set of tools which aim to make it easier to write code which can be built successfully on a wide range of target systems. Some would argue that autoconf is too complex a system to solve just the one problem you pose with just one library function, but as any program grows, it's likely to face more hurdles like this, and getting autoconf set up for your program now will put you in a much stronger position for the future.
Start with a file called Makefile.in which contains:
CFLAGS=--ansi --pedantic -Wall -W
program: program.o
program.o: program.c
clean:
rm -f program.o program
and a file called configure.ac which contains:
AC_PREREQ([2.69])
AC_INIT(program, 1.0)
AC_CONFIG_SRCDIR([program.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for library functions.
AH_TEMPLATE([HAVE_ITOA], [Set to 1 if function atoi() is available.])
AC_CHECK_FUNC([itoa],
[AC_DEFINE([HAVE_ITOA], [1])]
)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and a file called program.c which contains:
#include <stdio.h>
#include "config.h"
#ifndef HAVE_ITOA
/*
* WARNING: This code is for demonstration purposes only. Your
* implementation must have a way of ensuring that the size of the string
* produced does not overflow the buffer provided.
*/
void itoa(int n, char* p) {
sprintf(p, "%d", n);
}
#endif
int main(void) {
char buffer[100];
itoa(10, buffer);
printf("Result: %s\n", buffer);
return 0;
}
Now run the following commands in turn:
autoheader: This generates a new file called config.h.in which we'll need later.
autoconf: This generates a configuration script called configure
./configure: This runs some tests, including checking that you have a working C compiler and, because we've asked it to, whether an itoa function is available. It writes its results into the file config.h for later.
make: This compiles and links the program.
./program: This finally runs the program.
During the ./configure step, you'll see quite a lot of output, including something like:
checking for itoa... no
In this case, you'll see that the config.h find contains the following lines:
/* Set to 1 if function atoi() is available. */
/* #undef HAVE_ITOA */
Alternatively, if you do have atoi available, you'll see:
checking for itoa... yes
and this in config.h:
/* Set to 1 if function atoi() is available. */
#define HAVE_ITOA 1
You'll see that the program can now read the config.h header and choose to define itoa if it's not present.
Yes, it's a long way round to solve your problem, but you've now started using a very powerful tool which can help you in a great number of ways.
Good luck!

trying to build and compile lua 5.3.3 with mingw , undefined reference error

SO basically i got the lua5.3.3 source code and i am trying to build it with mingw
what i have done so far is that i did the whole operation in msys and then copied over the lib files and bin files and include files to mingw appropriate folders
however when i try to actually compile an application that uses it, i get these errors
this is the command i used to compile my program that uses lua
gcc syx.cpp -llua
C:\Users\User\AppData\Local\Temp\cckJPF8N.o:syx.cpp:(.text+0xf): undefined reference to `luaL_newstate()'
C:\Users\User\AppData\Local\Temp\cckJPF8N.o:syx.cpp:(.text+0x21): undefined reference to `luaL_openlibs(lua_State*)'
C:\Users\User\AppData\Local\Temp\cckJPF8N.o:syx.cpp:(.text+0x3e): undefined reference to `luaL_loadfilex(lua_State*, char const*, char const*)'
C:\Users\User\AppData\Local\Temp\cckJPF8N.o:syx.cpp:(.text+0x77): undefined reference to `lua_pcallk(lua_State*, int, int, int, int, int (*)(lua_State*, int, int))'
C:\Users\User\AppData\Local\Temp\cckJPF8N.o:syx.cpp:(.text+0x87): undefined reference to `lua_close(lua_State*)'
collect2.exe: error: ld returned 1 exit status
and here is the file(very basic) in case you need to see it
#include <stdio.h>
#include <lua5.3/lua.h>
#include <lua5.3/lualib.h>
#include <lua5.3/lauxlib.h>
/* the Lua interpreter */
lua_State* L;
int main ( int argc, char *argv[] )
{
L = luaL_newstate();
luaL_openlibs(L);
luaL_dofile(L, "test.lua");
/* cleanup Lua */
lua_close(L);
return 0;
}
i know the library file exists since it was created with mingw namely liblua.a which sits in my mingw lib folder , as well as the other files related to lua such as lua.exe luac.exe the include files etc so i am not sure what else is missing
Okay i found the solution
turns out gcc is mangling the symbols from the library header(whatever that means)
what needs to be done is the headers need to be wrapped in a extern "C" {//headers} to make it work
reference is here :
http://www.linuxquestions.org/questions/programming-9/undefined-reference-error-when-using-lua-api-892782/
and just to be clear, here is a working example:
#include <stdio.h>
extern "C"{
#include <lua5.3/lua.h>
#include <lua5.3/lualib.h>
#include <lua5.3/lauxlib.h>
}
/* the Lua interpreter */
lua_State* L;
int main ( int argc, char *argv[] )
{
L = luaL_newstate();
luaL_openlibs(L);
luaL_dofile(L, "test.lua");
/* cleanup Lua */
lua_close(L);
return 0;
}

Link to a DLL in Pelles C

I have a 218KB .dll and a 596KB .so file, both with identical names. I want to link to the .dll to avoid the "unresolved external symbol" error that the linker returns, but I can't find a way to link to the DLL file.
According to this Pelles C forum topic, I need to use the .def file to create a .lib... but I don't have a .def file. This forum topic shows how to use polink to create a .lib from the command line, so I ran polink /? to get some more options. I noticed a /MAKEDEF option, but running this with both the .dll and the .so gives a "No library file specified" fatal error.
I have been trying to do this for three hours, and am out of ideas. I have got to the point where my web searches turn up my own help-requests. There must be a way to do this... How can I link to a .dll?
With information found in the header #include and your details, here is a way to replace the missing function by calling them dynamically from your software.
1- the following prototype is in #include :
typedef float (* XPLMFlightLoop_f)(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon);
2- some const that you can fill as needed:
const char *sDllPathName = "<Your XPLM_API DLL>.dll";
const char *sXPLMRegisterFlightLoopCallbackName = "XPLMRegisterFlightLoopCallback";
In order to confirm the sXPLMRegisterFlightLoopCallbackName, you can
use the freeware Dependency Walker and check name and format of
the exported functions.
3- declare the prototype of the external function:
Be aware to the calling convention __cdecl or __stdcall
In the current case, the keyword XPLM_API is defined in the XPLMDefs.h as follow:
#define XPLM_API __declspec(dllexport) // meaning __cdecl calling convention
typedef void (__cdecl *XPLMRegisterFlightLoopCallback_PROC)(XPLMFlightLoop_f, float, void *);
4- clone the function to call it in your software:
#include <windows.h>
void XPLMRegisterFlightLoopCallback(XPLMFlightLoop_f inFlightLoop, float inInterval, void * inRefcon)
{
HINSTANCE hInstDLL;
XPLMRegisterFlightLoopCallback_PROC pMyDynamicProc = NULL;
// Load your DLL in memory
hInstDLL = LoadLibrary(sDllPathName);
if (hInstDLL!=NULL)
{
// Search for the XPLM Function
pMyDynamicProc = (XPLMRegisterFlightLoopCallback_PROC) GetProcAddress(hInstDLL, sXPLMRegisterFlightLoopCallbackName);
if (pMyDynamicProc != NULL)
{
// Call the XPLM Function with the orignal parameter
(pMyDynamicProc)(inFlightLoop,inInterval,inRefcon);
return;
}
}
// Do something when DLL is missing or function not found
}
5- just add your described call:
...
XPLMRegisterFlightLoopCallback(callbackfunction, 0, NULL);
...

Undefined reference in C

I have include unsigned short crc_message(unsigned int key, unsigned char *message, int num_bytes); in my "data.h"
But when I try to use it in another code file
...
#include "data.h"
unsigned short crc16 = crc_message(XMODEM_KEY, buff, nread);
...
I always get
In function main':/h/u8/g3/00/g3helios/p33/g3helios/a2/packetize.c:57: undefined reference tocrc_message'collect2: ld returned 1 exit status
Can someone tell me why? Thanks!
I think you have to find crc_message() function in some library regarding crc and compile your program against it - for example if the library is called libcrc.so you have to do:
gcc -lcrc ...
1.In header file data.h you have provided the prototype of function crc_message.
2.But, your problem is undefined reference error during linking stage.
3.So,did you define the function crc_message anywhere in your source ?

undefined reference to `__lzcnt16?

I have this code which I'm trying to run with GCC-TDM 1.7.4-2 using -msse4.2 (I tried msse4) with an error:
sse_lzcnt.c|7|warning: implicit declaration of function '__lzcnt16'|
sse_lzcnt.c|9|warning: too many arguments for format|
obj\Debug\sse_lzcnt.o||In function `main':|
sse_lzcnt.c|7|undefined reference to `__lzcnt16'|
An undefined reference is usually a linking error due to a missing lib file (.a ending) but the intrinsics headers don't need one?
I made sure the intrinsics headers are in the correct include directory. Heres the code,
#include <x86intrin.h>
#include <stdio.h>
int main()
{
unsigned short __X = 256;
unsigned short RESULT = __lzcnt16(__X);
printf("result: ", RESULT);
return 0;
}
You need to use the gcc command line option: -mlzcnt

Resources