learningtofly learningtofly - 3 months ago 9
C Question

Why is a function in a C header file available in main.c, but errors as undefined at compile time?

I have a C project in Eclipse (Neon) on Ubuntu 15.10. I have downloaded the OpenSSL library.

I have included

openssl/bn.h
in my preprocessor directives. In my
main.c
file, I can refer to
BN_new()
, a function in
bn.h
:

bn.h

However, when I try to compile, I get an undefined reference for all calls into
bn.h
(
BN_new()
,
BN_free()
, etc).

BN_new undefined

As a side note, I copied the contents of
openssl-1.0.2h/include/openssl
to my
/usr/include/
directory.

Why is this error happening at compile time?

my code:

#include <stdio.h>
#include "jpake.h"
#include <openssl/crypto.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <memory.h>

/*
* In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
* Bob's (x3, x4, x1, x2). If you see what I mean.
*/
typedef struct
{
char *name; /* Must be unique */
char *peer_name;
BIGNUM *p;
BIGNUM *g;
BIGNUM *q;
BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
} JPAKE_CTX_PUBLIC;


struct JPAKE_CTX
{
JPAKE_CTX_PUBLIC p;
BIGNUM *secret; /* The shared secret */
BN_CTX *ctx;
BIGNUM *xa; /* Alice's x1 or Bob's x3 */
BIGNUM *xb; /* Alice's x2 or Bob's x4 */
BIGNUM *key; /* The calculated (shared) key */
};

static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
{
zkp->gr = BN_new();
zkp->b = BN_new();
}

static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
{
BN_free(zkp->b);
BN_free(zkp->gr);
}

typedef struct
{
const char *name; //must be unique
int base; //1 for Alice, 3 for Bob. Only used for printing stuff


}JPakeUserPublic;


typedef struct
{
JPakeUserPublic p;
BIGNUM *secret; //the shared secret
BIGNUM *key; //the calculated (shared) key
BIGNUM *xa; //ALice's x1 or Bob's x3
BIGNUM *xb; //ALice's x2 or Bob's x4

}JPakeUser;

int main(int argc, char **argv)
{
JPakeUser alice, bob;
alice.p.name = "Alice";
alice.p.base = 1;
bob.p.name = "Bob";
bob.p.base = 3;

puts(alice.p.name);
}


I am not a new developer but I AM new to C and eclipse so I have been battling this for awhile. I have been experimenting with the makefile for this project also. Here is my makefile (it is modified from a C++ example):

all: hash4.exe

clean:
rm jpakedemo.o hash4.exe

hash4.exe: jpakedemo.c
gcc -g -o hash4 jpakedemo.c

jpakedemo.o:
gcc -c -g jpakedemo.c

Answer

The purpose of a .h header file is to describe what a particular function "looks like," so that correct code can be generated to make a call to that function.

But this, by itself, does not provide the function itself!

The final process of "linking all of the various compiler-outputs and libraries into 'a complete thing that can actually be run'" is performed by a separate program altogether ... which, appropriately enough, is called a "linker."

The subroutines that you refer-to could come from several places:   from another, separately-compiled, source program, or from a library. (If from a library, that library might be "statically" or "dynamically" linked.) Nevertheless, somehow, the necessary object-code must be found, so that they can be incorporated into the final executable.

OpenSSL subroutines, undoubtedly, come from a library (that is part of OpenSSL). Therefore, your Eclipse project probably does not presently contain a reference to that library, so that it can be found when needed.

Comments