# Things to remember when compiling/linking C/C++ software

by Angel Leon. March 17, 2015; August 29, 2019.

## Include Paths

On the compilation phase, you will usually need to specify the different include paths so that the interfaces (.h, .hpp) which define structs, classes, constans, and functions can be found.

With gcc and llvm include paths are passed with -I/path/to/includes, you can pass as many -I as you need.

In Windows, cl.exe takes include paths with the following syntax:
/I"c:\path\to\includes\ you can also pass as many as you need.

Some software uses macro definition variables that should be passed during compile time to decide what code to include.

## Compilation flags

These compilation-time variables are passed using -D,
e.g. -DMYSOFTWARE_COMPILATION_VARIABLE -DDO_SOMETHING=1 -DDISABLE_DEPRECATED_FUNCTIONS=0

These compilation time flags are by convention usually put into a single variable named CXXFLAGS, which is then passed to the compiler as a parameter for convenience when you’re building your compilation/make script.

## Object files

When you compile your .c, or .cpp files, you will end up with object files.
These files usually have .o extensions in Linux, in Windows they might be under .obj extensions.

You can create an .o file for a single or for many source files.

## Static Library files

When you have several .o files, you can put them together as a library, a static library. In Linux/Mac these static libraries are simply archive files, or .a files. In windows, static library files exist under the .lib extension.

They are created like this in Linux/Mac:

ar -cvq libctest.a ctest1.o ctest2.o ctest3.o

libctest.a will contain ctest1.o,ctest2.o and ctest2.o

They are created like this in Windows:

LIB.EXE /OUT:MYLIB.LIB FILE1.OBJ FILE2.OBJ FILE3.OBJ

When you are creating an executable that needs to make use of a library, if you use these static libraries, the size of your executable will be the sum of all the object files statically linked by the executable. The code is right there along the executable, it’s easier to distribute, but again, the size of the executable can be bigger than it needs to… why? because, sometimes, many of the .o files, or even the entire .a file you’re linking against might be a standard library that many other programs need.

## Shared Libraries (Dynamic Libraries)

So shared or dynamic libraries were invented so that different programs or libraries would make external (shared) references to them, since they’re “shared” the symbols defined in them don’t need to be part of your executable or library, your executable contain symbols whose entry points or offset addresses might point to somewhere within themselves, but they will also have symbols whose entry points are expected to exist on shared libraries which need only be loaded once in a single portion of the operating shared memory, thus not just making the size of your executable as small as it needs to be, but you won’t need to load the library for every process/program that needs its symbols.

On Linux shared files exist under the .so (shared object) file extension, on Mac .dylib (dynamic library), and in Windows they’re called .dll (dynamic link libraries)

Another cool thing about dynamic libraries, is that they can be loaded during runtime, not just linked at compile time. An example of runtime dynamic libraries are browser plugins.

In Linux .so files are created like this:

gcc -Wall -fPIC -c *.c
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0   *.o

• -Wall enables all warnings.
• -c means compile only, don’t run the linker.
• -fPIC means “Position Independent Code”, a requirement for shared libraries in Linux.
• -shared makes the object file created shareable by different executables.
• -Wl passes a comma separated list of arguments to the linker.
• -soname means “shared object name” to use.
• -o <my.so> means output, in this case the output shared library

In Mac .dylib files are created like this:

clang -dynamiclib -o libtest.dylib file1.o file2.o -L/some/library/path -lname_of_library_without_lib_prefix

In Windows .dll files are created like this:

LINK.EXE /DLL /OUT:MYLIB.DLL FILE1.OBJ FILE2.OBJ FILE3OBJ

When linking your software you may be faced with a situation on which you want to link against several standard shared libraries.
If all the libraries you need exist in a single folder, you can set the LD_LIBRARY_PATH to that folder. By common standard all shared libraries are prefixed with the word lib. If a library exists in LD_LIBRARY_PATH and you want to link against it, you don’t need to pass the entire path to the library, you simply pass -lname and you will link your executable to the symbols of libname.so which should be somewhere inside LD_LIBRARY_PATH.

Tip: You should probably stay away from altering your LD_LIBRARY_PATH, if you do, make sure you keep its original value, and when you’re done restore it, as you might screw the build processes of other software in the system which might depend on what’s on the LD_LIBRARY_PATH.

### What if libraries are in different folders?

If you have some other libbar.so library on another folder outside LD_LIBRARY_PATH you can explictly pass the full path to that library /path/to/that/other/library/libbar.so, or you can specify the folder that contains it -L/path/to/that/other/library and then the short hand form -lbar. This latter option makes more sense if the second folder contains several other libraries.

## Useful tools

Sometimes you may be dealing with issues like undefined symbol errors, and you may want to inspect what symbols (functions) are defined in your library.

On Mac there’s otool, on Linux/Mac there’s nm, on Windows there’s depends.exe (a GUI tool that can be used to see both dependencies and the symbol’s tables. Taking a look at the “Entry Point” column will help you understand clearly the difference between symbols linking to a shared library vs symbols linking statically to the same library)

### Useful command options

See shared library dependencies on Mac with otool

otool -L libjlibtorrent.dylib
libjlibtorrent.dylib:
libjlibtorrent.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)


See shared symbols with nm (Linux/Mac)
With nm, you can see the symbol’s name list.
Familiarize yourself with the meaning of the symbol types:

• T (text section symbol)
• U (undefined – useful for those undefined symbol error),
• I (indirect symbol).

If the symbol is local (non-external) the symbol type is presented in lowercase letters, for example a lowercase u represents an undefined reference to a private external in another module in the same library.

nm‘s documentation says that if you’re working on Mac and you see that the symbol is preceeded by + or - it means it’s an ObjectiveC method, if you’re familiar with ObjectiveC you will know that + is for class methods and - is for instance methods, but in practice it seems to be a bit more explicit and you will often see objc or OBJC prefixed to those methods.

nm is best used along with grep 😉

Find all Undefined symbols

nm -u libMacOSXUtilsLeopard.jnilib
_CFRelease
_LSSharedFileListCopySnapshot
_LSSharedFileListCreate
_LSSharedFileListInsertItemURL
_LSSharedFileListItemRemove
_LSSharedFileListItemResolve
_OBJC_CLASS_$_NSArray _OBJC_CLASS_$_NSAutoreleasePool
_OBJC_CLASS_$_NSDictionary _OBJC_CLASS_$_NSMutableArray
_OBJC_CLASS_$_NSMutableDictionary _OBJC_CLASS_$_NSString
_OBJC_CLASS_$_NSURL __Block_copy __NSConcreteGlobalBlock __dyld_register_func_for_add_image __objc_empty_cache __objc_empty_vtable _calloc _class_addMethod _class_getInstanceMethod _class_getInstanceSize _class_getInstanceVariable _class_getIvarLayout  ### My C++ code compiles but it won’t link Linking is simply “linking” a bunch of .o files to make an executable. Each one of these .o’s may be compiled on their own out of their .cpp files, but when one references symbols that are supposed to exist in other .o’s and they’re not to be found then you get linking errors. Perhaps through forward declarations you managed your compilation phase to pass, but then you get a bunch of symbol not found errors. Make sure to read them slowly, see where these symbols are being referenced, you will see that these issues occur due to namespace visibility in most cases. Perhaps you copied the signature of a method that exists in a private space elsewhere into some other namespace where your code wasn’t compiling, all you did was make it compilable, but the actual symbol might not be visible outside the scope where it’s truly defined and implemented. Function symbols can be private if they’re declared inside anonymous namespaces, or if they’re declared as static functions. An example: Undefined symbols for architecture x86_64: "FlushStateToDisk(CValidationState&, FlushStateMode)", referenced from: Network::TxMessage::handle(CNode*, CDataStream&, long long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool, bool) in libbitcoin_server.a(libbitcoin_server_a-TxMessage.o)  Here, when I read the code of Network::TxMessage::handle(...) there was a call to FlushStateToDisk, which was declared in main.h, and coded in main.cpp. My TxMessage.cpp did include main.h, compilation was fine, I had a TxMessage.o file and a main.o, but the linker was complaining. The issue was that FlushStateToDisk was declared as a static, therefore only visible inside main.o, once I removed the static from the declaration and implementation the error went away and my executable was linked. Similar things happen when functions are declared in anonymous spaces in other files, even if you forward declare them on your local .h In other cases your code compiles and you get this error linking because your library can’t be added using -lfoo, and adding its containing folder to -L doesn’t cut it, in this case you just add the full path to the library in your compilation command: gcc /path/to/the/missing/library.o ... my_source.cpp -o my_executable ### Reminder: DO NOT EXPORT CFLAGS, CPPFLAGS and the like on your .bash_profile/.bashrc, it can lead to unintended building consequences in many projects. I’ve wasted so many hours due to this mistake. # [CODE] Arduino 4 BIT LED binary counter Here’s my “Hello World” on Arduino. A 4-bit binary counter for arduino. If you add another LED on the 5th pin, then it can count from 0 to 31 (32 values) Circuit wired by @KataySantos int counter = -1; int MAX_VALUE = 16; void updateLED(int pin, int bit, int ctr) { digitalWrite(pin, (ctr & (1<<bit)) == (1<<bit) ? HIGH : LOW); } void setup() { // this runs once pinMode(1, OUTPUT); pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); } void loop() { // this runs repeatedly counter = (counter + 1) % MAX_VALUE; updateLED(1, 0, counter); updateLED(2, 1, counter); updateLED(3, 2, counter); updateLED(4, 3, counter); delay(500); } # How to create a list that holds different object types using void* in C. I remember being in school back around 1998 and not knowing enough about C to do this. After coding in other languages, then going back to C++ and understanding at a lower level how references and pointers work, this was pretty easy to figure out. In this exercise I store elements of different types in a forward linked list. In order to know what to dereference as I iterate through the list’s elements, I’ve put a “.type” field, which has an int value representing the type of the object stored. The “.value” is simply a void*, which lets me store a pointer of any kind, and it works pretty well. Here’s the code for your enjoyment, I hope this is useful to C apprentices. The example shows how you can store native types like int, or more complex char* or even a struct person* (which is the more useful probably to your purposes) It’s a good exercise to see the uses of the “address of” operator “&”, which is used to initialize pointers (the ‘&’ can also be used differently to create references, which I call in my mind as ‘aliases’, but this is not shown in this example) I also play with a not so popular syntax to access a pointer’s sub-fields: (*myPointer).structField == myPointer-&gt;structField to teach you that the -&gt; is a short hand for dereferencing a pointer and accessing one of its fields. // // An exercise to play with a struct that stores anything using a void* field. // #include <stdio.h> #define TRUE 1 int TYPE_INT = 0; int TYPE_STRING = 1; int TYPE_BOOLEAN = 2; int TYPE_PERSON = 3; struct node { struct node* next; int type; void* value; }; struct person { char* name; int age; }; int main(int args, char **argv) { struct person aPerson; aPerson.name = "Angel"; aPerson.age = 35; // Define a linked list of objects. // We use that .type field to know what we're dealing // with on every iteration. On .value we store our values. struct node nodes[] = { { .next = &nodes[1], .type = TYPE_INT , .value=1 }, { .next = &nodes[2], .type = TYPE_STRING , .value="anyfing, anyfing!" }, { .next = &nodes[3], .type = TYPE_PERSON , .value=&aPerson }, { .next = NULL , .type = TYPE_BOOLEAN, .value=TRUE } }; // We iterate through the list for ( struct node *currentNode = &nodes[0]; currentNode; currentNode = currentNode->next) { int currentType = (*currentNode).type; if (currentType == TYPE_INT) { printf("%s: %dn", "- INTEGER", (*currentNode).value); // just playing with syntax, same as currentNode->value } else if (currentType == TYPE_STRING) { printf("%s: %sn", "- STRING", currentNode->value); } else if (currentType == TYPE_BOOLEAN) { printf("%s: %dn", "- BOOLEAN (true:1, false:0)", currentNode->value); } else if (currentType == TYPE_PERSON) { // since we're using void*, we end up with a pointer to struct person, which we *dereference // into a struct in the stack. struct person currentPerson = *(struct person*) currentNode->value; printf("%s: %s (%d)n","- TYPE_PERSON", currentPerson.name, currentPerson.age); } } return 0; } The output is this: - INTEGER: 1 - STRING: anyfing, anyfing! - TYPE_PERSON: Angel (35) - BOOLEAN (true:1, false:0): 1  # # Things to remember when compiling/linking C/C++ software by Angel Leon. March 17, 2015. ## Include Paths On the compilation phase, you will usually need to specify the different include paths so that the interfaces (.h, .hpp) which define structs, classes, constans, and functions can be found. With gcc and llvm include paths are passed with -I/path/to/includes, you can pass as many -I as you need. In Windows, cl.exe takes include paths with the following syntax: /I"c:\path\to\includes\ you can also pass as many as you need. Some software uses macro definition variables that should be passed during compile time to decide what code to include. ## Compilation flags These compilation-time variables are passed using -D, e.g. -DMYSOFTWARE_COMPILATION_VARIABLE -DDO_SOMETHING=1 DDISABLE_DEPRECATED_FUNCTIONS=0 These compilation time flags are by convention usually put into a single variable named CXXFLAGS, which is then passed to the compiler as a parameter for convenience when you’re building your compilation/make script. ## Object files When you compile your .c, or .cpp files, you will end up with object files. These files usually have .o extensions in Linux, in Windows they might be under .obj extensions. You can create an .o file for a single or for many source files. ## Static Library files When you have several .o files, you can put them together as a library, a static library. In Linux/Mac these static libraries are simply archive files, or .a files. In windows, static library files exist under the .lib extension. They are created like this in Linux/Mac: ar -cvq libctest.a ctest1.o ctest2.o ctest3.o libctest.a will contain ctest1.o,ctest2.o and ctest2.o They are created like this in Windows: LIB.EXE /OUT:MYLIB.LIB FILE1.OBJ FILE2.OBJ FILE3.OBJ When you are creating an executable that needs to make use of a library, if you use these static libraries, the size of your executable will be the sum of all the object files statically linked by the executable. The code is right there along the executable, it’s easier to distribute, but again, the size of the executable can be bigger than it needs to… why? because, sometimes, many of the .o files, or even the entire .a file you’re linking against might be a standard library that many other programs need. ## Shared Libraries (Dynamic Libraries) So shared or dynamic libraries were invented so that different programs or libraries would make external (shared) references to them, since they’re “shared” the symbols defined in them don’t need to be part of your executable or library, your executable contain symbols whose entry points or offset addresses might point to somewhere within themselves, but they will also have symbols whose entry points are expected to exist on shared libraries which need only be loaded once in a single portion of the operating shared memory, thus not just making the size of your executable as small as it needs to be, but you won’t need to load the library for every process/program that needs its symbols. On Linux shared files exist under the .so (shared object) file extension, on Mac .dylib (dynamic library), and in Windows they’re called .dll (dynamic link libraries) Another cool thing about dynamic libraries, is that they can be linked during runtime, not just compile time. An example of runtime dynamic libraries are browser plugins. In Linux .so files are created like this: gcc -Wall -fPIC -c *.c gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o  • -Wall enables all warnings. • -c means don’t run the linker. • -fPIC means “Position Independent Code”, a requirement for shared libraries in Linux. • -shared makes the object file created shareable by different executables. • -Wl passes a comma separated list of arguments to the linker. • -soname means “shared object name” to use. In Mac .dylib files are created like this: clang -dynamiclib -o libtest.dylib file1.o file2.o -L/some/library/path -lname_of_library_without_lib_prefix In Windows .dll files are created like this: LINK.EXE /DLL /OUT:MYLIB.DLL FILE1.OBJ FILE2.OBJ FILE3OBJ ## Linking to existing libraries When linking your software you may be faced with a situation on which you want to link against several standard shared libraries. If all the libraries you need exist in a single folder, you can set the LD_LIBRARY_PATH to that folder. By common standard all shared libraries are prefixed with the word lib. If a library exists in LD_LIBRARY_PATH and you want to link against it, you don’t need to pass the entire path to the library, you simply pass -lname and you will link your executable to the symbols of libname.so which should be somewhere inside LD_LIBRARY_PATH. Tip: You should probably stay away from altering your LD_LIBRARY_PATH, if you do, make sure you keep its original value, and when you’re done restore it, as you might screw the build processes of other software in the system which might depend on what’s on the LD_LIBRARY_PATH. If you have some other libbar.so library on another folder outside LD_LIBRARY_PATH you can explictly pass the full path to that library /path/to/that/other/library/libbar.so, or you can specify the folder that contains it -L/path/to/that/other/library and then the short hand form -lbar. This latter option makes more sense if the second folder contains several other libraries. ## Useful tools Sometimes you may be dealing with issues like undefined symbol errors, and you may want to inspect what symbols (functions) are defined in your library. On Mac there’s otool, on Linux/Mac there’s nm, on Windows there’s depends.exe (a GUI tool that can be used to see both dependencies and the symbol’s tables. Taking a look at the “Entry Point” column will help you understand clearly the difference between symbols linking to a shared library vs symbols linking statically to the same library) ### Useful command options See shared library dependencies on Mac with otool otool -L libjlibtorrent.dylib libjlibtorrent.dylib: libjlibtorrent.dylib (compatibility version 0.0.0, current version 0.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)  See shared symbols with nm (Linux/Mac) With nm, you can see the symbol’s name list. Familiarize yourself with the meaning of the symbol types: * T (text section symbol) * U (undefined – useful for those undefined symbol error), * I (indirect symbol). * If the symbol is local (non-external) the symbol type is presented in lowercase letters, for example a lowercase u represents an undefined reference to a private external in another module in the same library. nm‘s documentation says that if you’re working on Mac and you see that the symbol is preceeded by + or - it means it’s an ObjectiveC method, if you’re familiar with ObjectiveC you will know that + is for class methods and - is for instance methods, but in practice it seems to be a bit more explicit and you will often see objc or OBJC prefixed to those methods. nm is best used along with grep 😉 Find all Undefined symbols nm -u libMacOSXUtilsLeopard.jnilib _CFRelease _LSSharedFileListCopySnapshot _LSSharedFileListCreate _LSSharedFileListInsertItemURL _LSSharedFileListItemRemove _LSSharedFileListItemResolve _NSFullUserName _OBJC_CLASS_$_NSArray
_OBJC_CLASS_$_NSAutoreleasePool _OBJC_CLASS_$_NSDictionary
_OBJC_CLASS_$_NSMutableArray _OBJC_CLASS_$_NSMutableDictionary
_OBJC_CLASS_$_NSString _OBJC_CLASS_$_NSURL
__Block_copy
__NSConcreteGlobalBlock
__objc_empty_cache
__objc_empty_vtable
_calloc
_class_getInstanceMethod
_class_getInstanceSize
_class_getInstanceVariable
_class_getIvarLayout


# Top Eclipse (IDE) features I can’t live without

(If you are in Windows, replace “Cmd” for “Ctrl”, and “Option” for “Alt”)

Cmd + 1: Create variables out of function’s outputs, get suggestions to fix issues.

“Shift + Cmd + T”: Open Type.

“Shift + Cmd + R”: Open Resource.

Select element and press “Option + Cmd + R” to rename a class, variable, method, the refactor will be performed throughout the entire project flawlessly.

Select element and press “Cmd + T”: Show Type Hierarchy, great to know what classes implement an interface, or what classes extend an abstract class.

# Setting up Eclipse as your IDE for Bitcoin C++ development on MacOSX.

If you are a Java developer used to the productivity levels achieved by working with eclipse’s code navigation, code completion and refactoring tools, it’s worth your time staying in eclipse for any sort of C++ development.

This post refers specifically to getting your eclipse environment to work with a particular C++ Open Source project, The Bitcoin Project.

Before you start setting up eclipse, please make sure you can build Bitcoin from the command line, this way you know that you have everything necessary to build Bitcoin, even if you’re still getting a few errors showing in Eclipse, in the end Eclipse will be using the Makefiles provided by the project whenever we need to compile (and it can do so incrementally when possible saving you a lot of compilation time)

I’m assuming you have installed:
– eclipse
eclipse CDT tools, up to date for the version of eclipse you’re working with (I’m still working with Juno)
– Qt/Eclipse plugin (optionally)
– All the dependencies (autoconf automake berkeley-db4 boost miniupnpc openssl pkg-config protobuf qt gdb) necessary to build Bitcoin which are easily installable via HomeBrew.

1. Let’s import the bitcoin/ project to our workspace.

File > Import > Existing Code as Makefile Project

Look for the bitcoin/ git checkout folder, and make sure you use the GNU Autotools Toolchain

Click Finish.

2. Fixing the C++ compiler Path and Symbols.

Right click on the project containing folder in the Project Explorer > Properties.
Go to C/C++ General > Paths and Symbols > Languages: GNU C++ >  “Includes” Tab and make sure it looks something like the screenshot below (I got those paths by looking at  the  ones used by the Makefiles in the Bitcoin. Hit Apply , OK, then wait for the reindexing, you might still have a few weird errors because of how the compiler checking settings are.

3. Remove a few more issues like “Error: Invalid arguments candidates are: void resize(?, int)."

We open again the project Properties, this time we go to C/C++ General > Preproessor Include Paths, Macros, etc.
Click on the Providers tab and make sure “CDT GCC Built-in Compiler Settings [Shared]” is checked. Hit Apply, OK, wait for reindexing.
If there are still errors, you might want to just delete them and refresh the project (F5 on the project folder in the Project explorer), all errors should be gone by now.

Now start working just as fast as you’re used to with Java on Eclipse.

Code completion…

Project wide renaming refactors in seconds…

Find references of variables, methods, classes (Cmd+Shift+G)

Find all the implementations of an interface (Cmd+T)

and best of all

Interactive debugging with gdb*

and all the tools you know and love from Eclipse.

*Setting up GDB debugging

To do step by step debugging you can use gdb, if you don’t have it installed just go to your Terminal and type brew install gdb.

On your command line, execute your Makefile to create an executable, once it appears on your Project Explorer you can Right click on it Debug As > Debug Configuration…

then make sure you have set gdb as the executable debugger in the “Debugger” configuration tab, then just set your breakpoints and debug away!

Not so fast… 🙁

As of Mac OSX 10.9, Apple decided that you cannot use gdb unless the gdb executable is signed with a certificate, they want you to use their super duper lldb debugger, but it’s still not compatible with Eclipse, you know, so you use their XCode IDE instead of what you want to use…

Anyways, signing the gdb at /usr/local/bin/gdb is not that hard.

To sign it you can create a certificate, or use an existing developer certificate. In my case, I already had a Mac Developer certificate so it was a very simple process, just issuing a single command in the Terminal and I finally got rid of the "Unable to find Mach task port for process-id 93213: (os/kern) failure (0x5).\n (please check gdb is codesigned - see taskgated(8))" error.

codesign -s “Name of my certificate here” /usr/local/bin/gdb

Then I tried debugging, I got a password dialog to verify I was the owner of the certificate, and then gdb could take over and then I could do my step by step debugging, with the ocassional crash.

Happy Hacking.

# How to actually build bitcoin on Mac OSX 10.9.1

First of all, if you have Macports, do yourself a favor and get rid of it.

Then make sure you have Homebrew installed and all the packages installed by it up to date.

1. Let’s install all the dependencies for Bitcoin hacking.

brew install autoconf automake berkeley-db4 boost miniupnpc openssl pkg-config protobuf qt libtool

2. Make sure you have the right OpenSSL version installed. Type the following on your terminal:

openssl version

you should see “OpenSSL 1.0.1f 6 Jan 2014.”

if you see an older version, do

brew update brew upgrade

OpenSSL should be upgraded, you may or may not have to issue a “brew link openssl” or even a “brew link --overwrite openssl” if it’s giving you trouble.

3. Now, let’s configure, and make. I strongly suggest you add the boost library path when configuring, otherwise you may get nasty “Undefined symbols for architecture x86_64” compilation errors. During the time I wrote this, homebrew had installed boost 1.55 in my system, and the boost lib path was /usr/local/Cellar/boost/1.55.0/lib so I invoked the following:

./configure --with-boost-libdir=/usr/local/Cellar/boost/1.55.0/lib

After that I just issued a

make

And I was done.

If you want to hack the bitcoin-qt client like me, head to src/qt/, there should be a bitcoin-qt executable there now.

Enjoy

# Function callbacks in C

Ever since I started programming in Javascript, and doing asynchronous function calls, I’ve found myself to be addicted to passing functions as parameters.

I do it a lot in python and php, it’s very easy to do this on all these dynamic typed languages.

I never had this concept of passing functions as parameters, or pointers to functions as parameters when I was a kid in school and we were doing stuff in C or Pascal, I’d deal with it with ifs and switches.

So, this afternoon I decided to read a little bit and give it a try in C.

Here’s some code for future reference If I ever need it, it’s pretty easy.

#include
void this() { printf("Thisn"); }
void that() { printf("Thatn"); }

int sum(int x, int y) {	return x+y; }

int mul(int x, int y) { return x*y; }

//Function that takes a callback that uses no parameters
void callanother(void (*callback)()) {
(*callback)();
}

//Function that takes a callback that
//takes 2 int parameters and returns int
int callComplexCallback(int (*callback)(),int a, int b) {
return (*callback)(a,b);
}

int main (int argc, char** argv) {
callanother(this);
callanother(that);

printf("n");

int w = 20;
int h = 30;

printf("%dn",callComplexCallback(sum,w,h));
printf("%dn",callComplexCallback(mul,w,h));

//this also works
printf("%dn",callComplexCallback((*sum),w,h));
printf("%dn",callComplexCallback((*mul),w,h));

return 0;
}


The output is this:

~\$ ./a.out
This
That

50
600
50
600


The whole trick is how you define the function that will take the other function as a parameter.

If you have a function:

void whatever();


The function that’s supposed to use “whatever()” like-functions should look:

void useWhateverLikeFunctions(void (*f)()) {
...
(*f)();
}


If you have a callback function that needs parameters, then you define the caller as:

void callerFunction(void (*f),int paramA, int* paramB, char paramC) {
...
(*f)(paramA,paramB,paramC);
}


Then you’d use the function

void someCallback(int a, int* b, char c);

...
callerFunction(someCallback,a,b,c);
...


I know this is the oldest thing in the world to C programmers, but it never crossed my mind before, so here it is for my own personal reference, I hope it serves others.