2016-08-10 9 views
-1

我在Ubuntu 15.10的Eclipse(Neon)中有一个C项目。我已经下载了OpenSSL库。为什么在main.c中可以使用C头文件中的函数,但是在编译时未定义错误?

我在预处理指令中包含了openssl/bn.h。在我main.c文件,可以参考我BN_new(),一个功能bn.h

bn.h

然而,当我尝试编译,我得到的所有调用一个未定义的引用到bn.hBN_new()BN_free()等) 。

BN_new undefined

作为一个方面说明,我复制的openssl-1.0.2h/include/openssl内容我/usr/include/目录。

为什么这个错误在编译时发生?

我的代码:

#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); 
} 

我不是一个新的开发者,但我是新来的C和日食所以我一直在争夺这一段时间。我一直在试验这个项目的makefile。这是我的生成文件(它是从一个C++例如修改):

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 
+3

请不要张贴链接图像;发布代码! –

+1

函数在头文件中被声明为*,但在'.c','.o'('.obj'),'.a'('.lib')或'.so'中被定义* ('.dll')文件。如果您只复制了* include *目录,那么您的函数*声明*,但不是* defined *。 – Amadan

+1

你应该发布你用来链接文件的命令。当您运行链接器时,您是否包含正确的库?对象文件的编译似乎工作正常;这是失败的链接。 –

回答

1

一个.h文件的目的是描述什么特定的功能“的模样”,使正确的代码可以生成拨打该功能。

但是,这本身并不提供的功能本身!

的最终过程“连接所有的各种编译器的输出和库成的‘一个完整事情,实际上可以是运行’”由单独的程序共进行...其中,适当地足够,被称为“链接器”。

您引用的子例程可能来自多个库位: 来自另一个独立编译的源程序,库。 (如果来自库,该库可能是“静态”或“动态”链接的)。但是,必须找到必要的对象代码,以便它们可以合并到最终的可执行文件中。

OpenSSL子程序无疑来自(这是OpenSSL的一部分)。因此,您的Eclipse项目可能目前不包含对该库的引用,以便在需要时可以找到它。

+0

谢谢你的回答。我将libssl.a和libcrypto.a添加到我的源代码目录,然后添加到我的生成文件并正确编译。我是C和eclipse的新手,所以这个答案是以我能够理解的方式编写的。 – learningtofly

+0

是的,说“它**正确链接**”会更准确。你会发现,'gcc'命令*(等)*通常都是这样做的:编译文件(生成包含目标代码的'.a'文件),然后*链接*所有东西以产生一个单独的(公平的)。 ..)自包含文件:“一个可执行文件”。因此执行两个不同的操作,但不显眼。 (Eclipse更详细地隐藏了详细信息。)通过将这两个(所谓的“静态”* vs *。“dynamic”...)库添加到组合中,可以使链接器成功找到所需的所有资源。 –

相关问题