Multiple C files required by single C++ block. How to build?

Hi,

I have some existing C-functions which I would like to include in a C++
signal processing block. The complication is that these C-functions are
located in a number of different files. I have created a C++ block which
uses these functions. It appears to build fine but when I come to
include the new block in my python script I get an “undefined symbol”
error referring to one of the low level C-functions (I think). In short,
is it possible to use my existing C-files unchanged (included in my C++
block)? If so what approach is necessary to make this work/build
properly?

I hope this makes sense.

Thanks a lot,

Jonas

=======================================================================
This email, including any attachments, is only for the intended
addressee. It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
altered or corrupted during transmission.

On Wednesday 29 November 2006 09:26, Jonas Hodel wrote:

I have some existing C-functions which I would like to include in a C+
signal processing block. The complication is that these C-functions are
located in a number of different files. I have created a C++ block which
uses these functions. It appears to build fine but when I come to
include the new block in my python script I get an “undefined symbol”
error referring to one of the low level C-functions (I think). In short,
is it possible to use my existing C-files unchanged (included in my C++
block)? If so what approach is necessary to make this work/build properly?

You need to compile those .c files into .o files and then link all your
.o
files together then it should work fine.

I don’t know how to get the GNURadio build system to do that for you
though
(probably just appending the names of the .c files to the list of source
files will do it though)

On Wed, Nov 29, 2006 at 10:39:20AM +1030, Daniel O’Connor wrote:

You need to compile those .c files into .o files and then link all your .o
files together then it should work fine.

I don’t know how to get the GNURadio build system to do that for you though
(probably just appending the names of the .c files to the list of source
files will do it though)

This is correct. You just need to arrange so that those files end up
in the same shared library as the block that’s using them.

Just add the the .c files to the _la_SOURCES entry in the
appropriate Makefile.am

Are you building this outside of the main tree a la
gr-howto-write-a-block, or in the main tree? The idea is the same in
both cases.

Does this make sense?

Eric

Hello,

Thanks to both Eric and Daniel for your prompt help.

Yes this does make sense and it was the first thing I tried. After it
didn’t work with my files I went right back to basics (I am building a
la gr-howto-write-a-block). I created very simple .h/.c files as a test.


/test.h/

#ifndef TEST
#define TEST

void jonas_test();

#endif


/test.c/

#include “test.h”
#include <stdio.h>

void jonas_test()
{
printf(“this is a test, proof is in the pudding\n”);
}


Then:
Within “howto_square2_ff.h” I added #include “test.h”.
Within “howto_square2_ff.cc” I added a call to jonas_test(), located in
the constructor howto_square2_ff ().
I added test.c to the “_howto_la_SOURCES” entry in
“src/lib/Makefile.am”.

Finally: “make clean”, “make” and “make check”.

This results in:

ImportError:
/home/jonas/gnuradio/gr-howto-write-a-block-3.0.2/src/lib/.libs/_howto.so:
undefined symbol: _Z10jonas_testv

I tired other variations (creating test.i, included in howto.i etc) but
I must be missing something fundamental.

Thanks again for you help!

Eric B. wrote:

is it possible to use my existing C-files unchanged (included in my C++

Does this make sense?

Eric

=======================================================================
This email, including any attachments, is only for the intended
addressee. It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
altered or corrupted during transmission.

Finally: “make clean”, “make” and “make check”.

This results in:

ImportError:
/home/jonas/gnuradio/gr-howto-write-a-block-3.0.2/src/lib/.libs/_howto.so:
undefined symbol: _Z10jonas_testv

What you need to do is to surround the declaration of jonas_testv() with
en extern “C” {} declaration. If you don’t do this, then the linker is
looking for the “mangled name” , which is C++'s way to embed type
declarations in a function name. If the function is declared in the .h
as extern “C”, it will just expect the function name with an underscore
in front of it, just like C does.

Cheers,
Jan

Hi Jonas,

Here are the steps I use to add a block. I piggyback onto
gnuradio-core/src/lib/general.

NOTE: I’m not saying this is the “right” way, but it works for me.

  1. Copy test.cc, test.h, and test.i to gnuradio-core/src/lib/general

  2. Edit gnuradio-core/src/lib/general/general.i, and add 2 new “include”
    lines (one for test.h and one for test.i)

  3. Edit gnuradio-core/src/lib/general/Makefile.am, and add the 3 new
    file
    names in the appropriate place

  4. In gnuradio-core, run “make” and “make install”

Hope this helps!

Patrick


From: Jonas Hodel [mailto:[email protected]]
Sent: Wednesday, November 29, 2006 1:05 PM
To: Eric B.
Cc: [email protected]
Subject: Re: [Discuss-gnuradio] Multiple C files required by single C++
block.How to build?

Hello,

Thanks to both Eric and Daniel for your prompt help.

Yes this does make sense and it was the first thing I tried. After it
didn’t
work with my files I went right back to basics (I am building a la
gr-howto-write-a-block). I created very simple .h/.c files as a test.



/test.h/

#ifndef TEST
#define TEST

void jonas_test();

#endif



/test.c/

#include “test.h”
#include <stdio.h>

void jonas_test()
{
printf(“this is a test, proof is in the pudding\n”);
}



Then:
Within “howto_square2_ff.h” I added #include “test.h”.
Within “howto_square2_ff.cc” I added a call to jonas_test(), located in
the
constructor howto_square2_ff ().
I added test.c to the “_howto_la_SOURCES” entry in
“src/lib/Makefile.am”.

Finally: “make clean”, “make” and “make check”.

This results in:

ImportError:
/home/jonas/gnuradio/gr-howto-write-a-block-3.0.2/src/lib/.libs/_howto.so:
undefined symbol: _Z10jonas_testv

I tired other variations (creating test.i, included in howto.i etc) but
I
must be missing something fundamental.

Thanks again for you help!

Eric B. wrote:

On Wed, Nov 29, 2006 at 10:39:20AM +1030, Daniel O’Connor wrote:

On Wednesday 29 November 2006 09:26, Jonas Hodel wrote:

I have some existing C-functions which I would like to include in a C+
signal processing block. The complication is that these C-functions are
located in a number of different files. I have created a C++ block which
uses these functions. It appears to build fine but when I come to
include the new block in my python script I get an “undefined symbol”
error referring to one of the low level C-functions (I think). In short,
is it possible to use my existing C-files unchanged (included in my C++
block)? If so what approach is necessary to make this work/build
properly?

You need to compile those .c files into .o files and then link all your
.o
files together then it should work fine.

I don’t know how to get the GNURadio build system to do that for you
though
(probably just appending the names of the .c files to the list of source
files will do it though)

This is correct. You just need to arrange so that those files end up
in the same shared library as the block that’s using them.

Just add the the .c files to the _la_SOURCES entry in the
appropriate Makefile.am

Are you building this outside of the main tree a la
gr-howto-write-a-block, or in the main tree? The idea is the same in
both cases.

Does this make sense?

Eric


This email, including any attachments, is only for the intended
addressee.
It is subject to copyright, confidential and may be the subject of legal
or
other privilege, none of which is waived or lost by reason of this
transmission. If the receiver is not the intended addressee, please
accept
our apologies, notify us by return, delete all copies and perform no
other
act on the email. Unfortunately, we cannot warrant that the email has
not
been altered or corrupted during transmission.


On Thursday 30 November 2006 06:35, Jonas Hodel wrote:

ImportError:
/home/jonas/gnuradio/gr-howto-write-a-block-3.0.2/src/lib/.libs/_howto.so:
undefined symbol: _Z10jonas_testv

I think this means that the compiler has generated a reference to a C++
symbol - note the mangling in front.

I think you need to tell the compiler it’s dealing with C when you
declare the
prototype for your C function.

I believe you do…
extern “C” {
#include “HeaderForMyCFunctions.h”
}

but my C++ fu is weak.

Fantastic, works like a charm! I thought the problem was in the way I
was using SWIG but the culprit was the C/C++ linkage. Now I can try it
with my original files.

Thanks for all the help!

Jonas

Jan S. wrote:

with en extern “C” {} declaration. If you don’t do this, then the
linker is looking for the “mangled name” , which is C++'s way to embed
type declarations in a function name. If the function is declared in
the .h as extern “C”, it will just expect the function name with an
underscore in front of it, just like C does.

Cheers,
Jan

=======================================================================
This email, including any attachments, is only for the intended
addressee. It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
altered or corrupted during transmission.