0

次の C コードのコンパイル/リンクに問題があります。リンカーは、次のようなエラーをスローします。

pso.o:pso.c:(.text+0x41): undefined reference to '_ps'
...
pso.o:pso.c:(.text+0x93): more undefined references to '_ps' follow

gcc の C コードを書くのはこれが初めてなので、この問題を解決する方法がわかりません。struct PS がヘッダー ファイルで定義されているため、何らかの形で pso.c にリンクされていないと想定しています。ただし、そのソース ファイルの先頭に #include "ps.h" ステートメントを使用しました。

関連するソース ファイルとヘッダー ファイル、および使用しているメイク ファイルを以下に示します。リンク可能な C コードを書くために欠けている基本的な概念はありますか?

ありがとうございました!ああ、あなたが疑問に思っているなら、それは粒子群オプティマイザーです:)

main.c ファイル:

#define MAIN
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include "ps.h"

int main(int argc, char *argv[])
{
  int c;
  double test;
  int test_int;

  srand(time(NULL));
  printf("starting pso\n");
  pso();
  printf("finished pso\n");
  return(0);
}

問題のファイル pso.c:

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

double it(double C[]);

void pso()
{
    int i;
    int j;
    int k;

    puts("Now in PSO");

    /* Initialize PSO controls */
    psoi();

    /* Initialize particle positions and velocities */
    for (i=0;i<MPART;i++){
        for(j=1;j<MINDV;j++){
            /* positions */
            ps.X[i][j]=(-1+2*random())*ps.bup;

            /* velocities */
            ps.V[i][j] = (-1+2*random())*ps.bup / ps.vred;

            /* Transform */
            ps.ut[j] = (ps.X[i][j] - ps.blo)/(ps.bup - ps.blo) * (ps.bnd_hi[i] - ps.bnd_lo[i]) + ps.bnd_lo[i];
        }

        /* Evaluate Finess */
        ps.fitness = fit(ps.ut);

        /* Update particle best position */
        ps.pbest[i]=ps.fitness;

        /* Update swarm best position */
        if(ps.pbest[i] < ps.sbest){
            for(j=0;j<MINDV;j++){
                ps.g[j]=ps.p[i][j];
            }
            ps.sbest = ps.pbest[i];
        }
    }

    /* Convergenve Loop */

    for(k=2;k<ps.maxk;k++){
        for(i=1;i<MPART;i++){
            for(j=1;j<MINDV;j++){
                /* Velocity Update */
                ps.rp = random();
                ps.rg = random();
                ps.rr = random();
                ps.chi = 0.7298;

                ps.V[i][j] = ps.chi * ( ps.V[i][j] + ps.phi_p*ps.rp*(ps.p[i][j] - ps.X[i][j]) + ps.phi_g*ps.rg*(ps.g[j] - ps.X[i][j]));

                /* Position Update */
                ps.X[i][j] = ps.X[i][j] + ps.V[i][j];
                /* Transform */
                ps.ut[j] = (ps.X[i][j]-ps.blo)/(ps.bup-ps.blo)*(ps.bnd_hi[i]-ps.bnd_lo[i])+ps.bnd_lo[i];
                }

            /* Evaluate Fitness */
            ps.fitness = fit(ps.ut);

            /* Update particle best position */
            if(ps.fitness < ps.pbest[i]){
                for(j=0;j<MINDV;j++){
                    ps.p[i][j]=ps.X[i][j];
                }
                ps.pbest[i]=ps.fitness;
            }

            /* Update swarm best position */
            if(ps.pbest[i] < ps.sbest){
                for(j=0;j<MINDV;j++){
                ps.g[j]=ps.p[i][j];
                }
            ps.sbest = ps.pbest[i];
            printf("%f \n",ps.sbest);
            }
        }

        /* Convergence Criteria */

    }
  /* return(0); */
 }

データ構造 PS (ps.h) を定義するヘッダー ファイル:

#ifndef _PS_
#define _PS_
#define MPART 30
#define MINDV 2

typedef struct{
  /* Design Space */
  double X[MPART][MINDV];
  double V[MPART][MINDV];
  double p[MPART][MINDV];
  double u[MINDV];
  double ut[MINDV];
  double sbest;
  double sbest_old;
  double g[MINDV];
  double gt[MINDV];
  double pbest[MPART];
  double pbest_sort[MPART];
  double blo;
  double bup;
  double fitness;
  double maxk;
  double bnd_lo[MINDV];
  double bnd_hi[MINDV];
  /* PSO behavior */
  int psotype;
  double w;
  double phi_p;
  double phi_g;
  double gam;
  double chi;
  double vred;
  double rp;
  double rg;
  double rr;
}PS;

/* Dependent Source File Functions */
extern void pso();
extern double fit(double C[2]);

#ifndef MAIN
extern PS ps;
#endif
#endif

最後に、私が使用しているメイクファイル:

CC=gcc
CFLAGS= -I.
DEPS = ps.h
OBJ = main.o pso.o psoi.o fit.o

default: program

%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

program: $(OBJ)
    gcc -o $@ $^ $(CFLAGS)
4

3 に答える 3

2

「ps.h」には、次の行があります

extern PS ps;

—しかし、これは宣言 psするだけです(つまり、それがどこかに存在すると主張します)。定義を提供しません(つまり、ここに存在させます)。あなたがすべきことは、ステップ1、交換することです

#ifndef MAIN
extern PS ps;
#endif

だけで

extern PS ps;

次に、ステップ2で、pso.cそのファイルの最上位のどこかに追加します

PS ps = {};

(またはPS ps;、またはextern PS ps = {};)。あなたの C コンパイラが古いか、中かっこが空であることに文句を言うほど馬鹿げている場合は、PS ps = {0};代わりに次のように記述してください。{}は、C'11 に採用されていると私が信じている C++'03 主義ですが、それについて 100% 確実ではありません。

簡単に言うと、宣言に関するルールは次のとおりです。初期化子に を指定する場合=、宣言は定義でなければなりません (他の方法でここで変数を初期化できるからです)。それ以外の場合、externストレージ クラスを使用した場合、それは定義ではありません(覚え方として、このファイルの外部に変数が存在すると言っているからです)。それ以外の場合、それは定義です (ただし、K&R C ではそれは暫定的な定義であり、多くのコンパイラはデフォルトで BSS セクションに配置するか、そうするコマンドライン オプションを提供します)。

于 2013-03-06T20:32:45.263 に答える
2

psリンカの出力は少し紛らわしいです。実際には、オブジェクトの定義が欠落していると不平を言っています。あなたはそれを宣言しましたがextern、どこにも定義していません。

于 2013-03-06T20:18:29.227 に答える
2

as として宣言 するだけで、実際にどこにも定義することはありません。書くpsextern

PS ps;

Cファイルの1つに。

于 2013-03-06T20:19:50.957 に答える