0

I'm trying to use libreDWG to open and understand some dwg files. I have installed it and at least got some of the test programs to run (even if they seg fault later on). Anyway, I have included a small header file in my project very similar to the simple example found here https://github.com/h4ck3rm1k3/libredwg/blob/master/examples/load_dwg.c There seems to be a general problem with data types (at least in the way I'm compiling it) meaning I've added a few casts of form (char*) to number of variables which previously trying to automatically convert (void*) and (unsigned char*) to type (char*) and got rid of those compiler complaints. But even still when I compile it like so

g++ xxx.c++ -L/opt/local/lib/ -lredwg -o program_name

I get the following error:

Undefined symbols for architecture x86_64:
    "dwg_read_file(char*, _dwg_struct*)", referenced from:
     load_dwg(char*)in ccN6HUqz.o
     "dwg_free(_dwg_struct*)", referenced from:
      load_dwg(char*)in ccN6HUqz.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

I'm not sure what to do, I've fixed any problems in the source the compiler complains about and am linking to the relevant libraries with -lredwg (right? I haven't missed any?). My header file is just to test the functionality and looks like:

#include "suffix.c"
#include <dwg.h>

plan floor_plan;//temporary data structure defined elsewhere for now


void
add_line(double x1, double y1, double x2, double y2)
{

    line_in temp;
    temp.start.x=x1;
    temp.start.y=y1;
    temp.end.x=x2;
    temp.end.y=y2;
    floor_plan.lines.push_back(temp);
    std::cout<<"LINE: :"<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<std::endl;

}

void
add_circle(double x, double y, double R)
{
    // Yet to do
}

void
add_text(double x, double y, char *txt)
{
    // Make something with that
}

int
load_dwg(char *filename)
{
    unsigned int i;
    int success;
    Dwg_Data dwg;

    dwg.num_objects = 0;
    success = dwg_read_file(filename, &dwg);
    for (i = 0; i < dwg.num_objects; i++)
    {
        Dwg_Entity_LINE *line;
        Dwg_Entity_CIRCLE *circle;
        Dwg_Entity_TEXT *text;

        switch (dwg.object[i].type)
        {
            case DWG_TYPE_LINE:
                line = dwg.object[i].tio.entity->tio.LINE;
                add_line(line->start.x, line->end.x, line->start.y, line->end.y);
                break;
            case DWG_TYPE_CIRCLE:
                circle = dwg.object[i].tio.entity->tio.CIRCLE;
                add_circle(circle->center.x, circle->center.y, circle->radius);
                break;
            case DWG_TYPE_TEXT:
                text = dwg.object[i].tio.entity->tio.TEXT;
                add_text(text->insertion_pt.x, text->insertion_pt.y, (char*) text->text_value);
                break;
        }
    }
    dwg_free(&dwg);
    return success;
}

What am I doing wrong? I believe libredwg is written in c. Is this the problem?

user3353819
  • 911
  • 2
  • 8
  • 21

1 Answers1

1

It seems that you are trying to link against a 32 bit library when you're on a 64 bit platform, like in this answer. Solution is to download (or build yourself from source) a 64 bit version of libredwg. Or alternatively add the "-m32" flag to your g++ command line - to build your whole app as a 32 bit executable.

EDIT : as you have found out, the problem is actually caused by trying to link C++ code with a C library without the following at the top / bottom of your code :

#ifdef __cplusplus 
extern "C" { 
#endif

// ... source code here

#ifdef __cplusplus
} 
#endif 

Basically this tells the compiler not to do C++ name-mangling - switching name mangling off allows linking between C and C++

Community
  • 1
  • 1
Graham Griffiths
  • 2,196
  • 1
  • 12
  • 15
  • Seems likely, tried the "-m32" command, had to fix some 'too big' numbers, but then all my other library dependencies exploded. (I'm using boost and fltk). How do I build a 64 bit version, I thought that surely that's what I did when I ran the makefile: $ ./configure [options] $ make $ make check $ make install How do I specify 64 bit? – user3353819 Mar 24 '14 at 14:41
  • run configure --help / have a skim through the configure script to see what options it supports? agree, it's supposed to auto-detect your platform settings and generate an appropriate makefile – Graham Griffiths Mar 24 '14 at 14:46
  • --build or --host seem pretty standard for configure – Graham Griffiths Mar 24 '14 at 14:46
  • helpful : http://stackoverflow.com/questions/5139403/whats-the-difference-of-configure-option-build-host-and-target – Graham Griffiths Mar 24 '14 at 14:48
  • It seemed so likely to work! I attempeted to reinstall with ./configure --host=x86_64 --build=x86_64 which worked but then when running make etc. it output just a couple of lines like 'make[1]: Nothing to be done for `all'.' When I tried compiling again it didn't work. Do I need to uninstall somehow or inform configure to overwrite existing instances? – user3353819 Mar 24 '14 at 15:02
  • And what I don't understand is that the bundled examples compiled fine... A couple of them even run without seg-faulting(!)... Including the one which is pretty much verbatim what I wrote above. – user3353819 Mar 24 '14 at 15:05
  • did you do a make clean? – Graham Griffiths Mar 24 '14 at 15:07
  • when you build the examples it must be building the whole thing in 32 bit mode...which probably works fine because it doesn't need boost / fltk – Graham Griffiths Mar 24 '14 at 15:08
  • Again, sounds right, but no joy. I'm now configuring as above and running $sudo make clean all $ sudo make install but still the same error. I'm still not sure if everything is now working in the scripting as it keeps outputing things like 'make[2]: Nothing to be done for `all-am'.' And bizarrely the example programs disappeared with the make clean command but are now not recompiling... – user3353819 Mar 24 '14 at 15:28
  • And looking at some of the output from configure there are entires like: checking for x86_64-ranlib... no checking for ranlib... ranlib – user3353819 Mar 24 '14 at 15:55
  • I think I'm getting to the crux of it. I can manually compile the examples now using gcc read_dwg.c -lredwg -o read_dwg but if I try g++ read_dwg.c -lredwg -o read.dwg I get the same error as before Undefined symbols for architecture x86_64: "dwg_read_file(char*, _dwg_struct*)", referenced from: load_dwg(char*)in cc4Bi8WF.o "dwg_free(_dwg_struct*)", referenced from: load_dwg(char*)in cc4Bi8WF.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status I have to write my project in c++, what do I do? – user3353819 Mar 24 '14 at 16:08
  • Good lord, that was painful, this was the solution (shows the holes in my knowledge): I needed to include the c files within #ifdef __cplusplus extern "C" { #endif and #ifdef __cplusplus } #endif Works now! Thanks for all the help though Graham. – user3353819 Mar 24 '14 at 16:24