注册 登录
编程论坛 C++教室

请教自建库使用的问题

rainbow1 发布于 2010-07-21 00:45, 1237 次点击
编写了一个产生随机数的程序,有头文件、函数文件,另编写主程序调用函数文件,程序正常输出。我把函数文件编译成.lib,设定好编译器路径,但在编译时通不过。
#include <iostream>
//#include "Dsp.cpp"  //直接用函数文件可以完成主程序的编译并正常运行。将此函数文件编译为 .lib
#include <dsp.h>//这是文件头。库文件为 .lib 。出问题了:
using namespace std;

int main()
{
    double uniMin, uniMax, x;
    int i, j;
    long int *s;
    cout << "此程序将产生均匀分布的随机数。" << endl;
    cout << "请输入均匀区间下限:" ;
    cin >> uniMin;
    cout << endl << "请输入均匀区间上限:" ;
    cin >> uniMax;
    cout << "请输入随机数种子:";
    cin >> *s;
    cout << "请看结果:" << endl;
   
    for( i = 0; i < 10; i++ )
    {
         for( j = 0; j < 5; j ++ )
         {
              x = UniForm( uniMin, uniMax, s );//问题出在对 s 的引用上。
              cout << x << "    ";
         }
         cout << endl;
    }
    system( "pause" );
    cin.get();
    return 0;
}
编译信息:Link Error:Undefined reference to "UniForm( double, double, long * );//什么叫未定义的引用?我另外定义一个引用别名也不行。
          ld return 1 exit status    //这句话是什么意思?
我直接调用函数文件就行,难道编译成库文件就不行?是不是自建库文件还需要设置什么项目?郁闷呀!
请高手帮忙解释一下。

用的是DEV-C++


//dsp.h内容如下:

#ifndef _dsp_h
#define _dsp_h
/*
函数UniForm在区间( a, b )产生 均匀分布的随机数
*/
double UniForm(double a, double b, long int *seed );
#endif


函数文件:
//dsp.cpp
#include "dsp.h"
//UniForm
double UniForm( double a, double b, long int *seed )
{
       double t;

       * seed = 2045 * ( * seed ) +1;
       * seed = * seed - ( * seed / 1048576 ) * 1048576;
       t = ( * seed ) / 1048576.0;
       t = a + ( b -a ) * t;

       return t;
}


头文件:
//dsp.h内容如下:

#ifndef _dsp_h
#define _dsp_h
/*
函数UniForm在区间( a, b )产生 均匀分布的随机数
*/
double UniForm(double a, double b, long int *seed );
#endif



[ 本帖最后由 rainbow1 于 2010-7-21 00:56 编辑 ]
13 回复
#2
rainbow12010-07-21 14:08
没有人帮忙?
#3
pangding2010-07-22 10:53
Undefined reference 就是编译器在链接的时候不知道这个函数的在什么地方。
它一开始写了 Link error: 链接错误, 就是说编译已经通过了。

我没用过 dev-c++,可能是要做点链接设置,比如告诉它库文件的路径,否则它自动只会去找系统库的位置做链接。
#4
rainbow12010-07-22 13:03
库文件和头文件的路径设置都没有问题。
在Dev-C++里设置好,无法链接;我把文件拷贝到Dev-C++里相应的目录下也不能链接。
#5
pangding2010-07-22 14:11
原来 .lib 是 VC 用的东西。dev  用的不是这种格式…… 你是怎么编译成 .lib 的?

dev 用的是 gcc 那应该很容易搞呀,你要会用命令行的话,其实不难。
我不知道在 windows 下应该怎么弄这个,你在多试试,可能有什么设置会有用吧。或者上网查查 dev 相关的使用教程之类的。
#6
pangding2010-07-22 14:24
库有两种,一种是静态的,一种是动态的。

静态的概念上稍微容易一点。就是有一个已经编译好了的库,然后我写代码可以用库的函数。但编译时要访问库的代码,并把相关的代码相当于拷贝到現在编译的代码上。由于编译时就静态的拷到了自己的程序里,运行的时候直接就可以用。
还一种就是动态的,那个编译的时候不用管,链接的时候得链过来。库的代码不在自己的程序里,还得运行的时候加载。所以是动态的。

概念上大概就是这样的。如果能上网查到教程里有操作方法的话,应该很快就能学会用。但原理可能比较复杂,不用去管也可以。
#7
rainbow12010-07-22 14:48
库是用命令行编译成的。我这属于静态的库。实在不行看改成动态的库再试一下。
#8
pangding2010-07-22 23:41
静态的应该也可以,只要告诉链接器在链接的时候把代码链接过来就行了。
gcc 的话, -L 指示库的路径,-l 指示把库链过来。
希望它认识 .lib 的文件,呵呵
#9
rainbow12010-07-23 12:47
我用BCB6.0编译也不过,出现同样的问题,说明与编译环境没有太大关系。现在看来应该是程序的问题。回头再仔细找一找相关的资料。
#10
pangding2010-07-24 01:02
我写了个演示用的小程序,但不知道我用的命令,你那里是不是都能用。

先来几个文件
p.h
程序代码:

#ifndef P_H
#define P_H

extern int a[];
extern void p();

#endif /* P_H */

data.c
程序代码:

#include "p.h"

int a[5] = { 1, 2, 3, 4, 5 };

func.c
程序代码:

#include "p.h"
#include <stdio.h>

void p()
{
    int i;

    for (i = 0; i < 5; i++) {
        printf("a[%d] = %d\n", i, a[i]);
    }
}

main.c
程序代码:

#include "p.h"

int main(int argc, char *argv[])
{
    p();

    return 0;
}

#11
pangding2010-07-24 01:06
把它们搁到一个文件夹下,然后:
$ ls                                ls 是列印当前目录下的文件
data.c  func.c  main.c  p.h
$ gcc -c data.c func.c              编译
$ ls                                生成的 *.o 是目标代码
data.c  data.o  func.c  func.o  main.c  p.h
$ ar rs libtest.a *.o               把它们打包成静态库
ar: creating libtest.a
$ ls
data.c  data.o  func.c  func.o  libtest.a  main.c  p.h
$ gcc main.c -L. -ltest             用 -L. 指示库在当前文件夹, -ltest 指示库的名字是 libtest.a
$ ls                                可执行文件就是那个 a.out
a.out  data.c  data.o  func.c  func.o  libtest.a  main.c  p.h
$ ./a.out                           跑跑看,没问题
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
$

#12
rainbow12010-07-25 23:37
收到楼上。回头仔细研究一下。由于我用的温豆死下的,可能会有些不同。呵呵。。。。
#13
pangding2010-07-26 00:03
嗯,windows 下的动态库比较复杂,还得弄 dll 什么的,我不是很懂。不过我想静态库应该区别不大。反正你查点资料吧,想做这些方面的东西,多多少少要学点相关的知识。
#14
saynotolx2010-07-26 17:20
高手云集啊
1