PDA

View Full Version : سوال: multiple definition of



arashmidos2020
پنج شنبه 12 فروردین 1389, 05:46 صبح
سلام.ارور multiple definition of رو چطوری میشه رفع کرد. مثلا من وقتی یک تابع به نام _init دارم در سورسم چطوری باید از اینکه در جای دیگه تعریف شده جلوگیری کنم؟

و دوم اینکه چطور میشه وقتی یک هدر وجود داره و کامپایلر می شناسدش وقتی میخوام از متغیرهایی که داخلش تعریف شده استفاده کنم میگه این متغیر هنوز تعریف نشده!! من می گم شاید فایل .so رو پیدا نکرده اما چطوری بهش اینو بفهمونم دوباره؟

my compiler is gcc ;)

sh4mid
پنج شنبه 12 فروردین 1389, 12:48 عصر
سلام
برای اینکه تعریف متغیرهات با هم اشتباه نشه می تونی از namespace استفاده کنی
برای سوال دوم هم بیا اون متغیرها رو تو برنامه خودت extern تعریف کن (البته زیاد مطمئن نیستم)

Nima_NF
پنج شنبه 12 فروردین 1389, 13:57 عصر
بله؛ همانطور که sh4mid گفتند:
در مورد اولی، اگر داخل بلاک های جداگانه نیستند، باید از namespace ها استفاده کنید.
توضیحات کامل و مثال در این لینک داده شده است. (http://barnamenevis.org/forum/showthread.php?t=138216)

در غیر این صورت باید نام های مختلف انتخاب کنید.


در مورد سوال دوم هم شما باید در فایل های دیگر که قصد استفاده از متغیر را دارید، از کلمه کلیدی extern استفاده کنید تا به کامپایلر بگویید که قبلا در سایر فایل تعریف شده است.
مثلا در فایل myfile.h متغیر x را از نوع int تعریف کرده اید، در فایل myfile2.cpp باید به شکل زیر در بالای فایل تعریف کنید :



extern int x;

arashmidos2020
پنج شنبه 12 فروردین 1389, 18:28 عصر
سلام
برای اینکه تعریف متغیرهات با هم اشتباه نشه می تونی از namespace استفاده کنی
برای سوال دوم هم بیا اون متغیرها رو تو برنامه خودت extern تعریف کن (البته زیاد مطمئن نیستم)

ممنون ولی جواب سوال من این نبود. می دونم با این دو مورد درست می شه اما من یک سورس کد دارم که قبل این به درستی کار می کرده!سورس هم می زارم اینجا.


#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <syslog.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <dlfcn.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include "gridbox.h"
#include "acl.h"
#include "syscalls.h"

/* File system functions */

static int(*true_chmod)(const char *, mode_t);
static int(*true_chown)(const char *, uid_t, gid_t);
static int(*true_chroot)(const char *);
static int(*true_creat)(const char *, mode_t);
static int(*true_fchmod)(int, mode_t);
static int(*true_fchown)(int, uid_t, gid_t);
static FILE *(*true_fopen)(const char *,const char*);
static int(*true_ftruncate)(int, TRUNCATE_T);
static int(*true_lchown)(const char *, uid_t, gid_t);
static int(*true_link)(const char *, const char *);
static int(*true_mkdir)(const char *, mode_t);
static int(*true_open)(const char *, int, ...);
static int(*true_rename)(const char *, const char *);
static int(*true_rmdir)(const char *);
static int(*true_symlink)(const char *, const char *);
static int(*true_truncate)(const char *, TRUNCATE_T);
static int(*true_unlink)(const char *);

#if(GLIBC_MINOR >= 1)
static int(*true_creat64)(const char *, __mode_t);
static FILE *(*true_fopen64)(const char *,const char *);
static int(*true_ftruncate64)(int, __off64_t);
static int(*true_open64)(const char *, int, ...);
static int(*true_truncate64)(const char *, __off64_t);
#endif

/* Network functions */
static int (*true_socket)(int domain, int type, int protocol);
static int (*true_connect)(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen);
static int (*true_bind)(int sockfd, const struct sockaddr *my_addr,
socklen_t addrlen);
static int (*true_listen)(int s, int backlog);

/* System functions */
static int (*true_system)(const char *command);

void _init(void) {

void *libc_handle;

libc_handle = RTLD_NEXT;

true_socket = dlsym(libc_handle, "socket");
true_connect = dlsym(libc_handle, "connect");
true_bind = dlsym(libc_handle, "bind");
true_listen = dlsym(libc_handle, "listen");

true_system = dlsym(libc_handle, "system");

true_chmod = dlsym(libc_handle, "chmod");
true_chown = dlsym(libc_handle, "chown");
true_chroot = dlsym(libc_handle, "chroot");
true_creat = dlsym(libc_handle, "creat");
true_fchmod = dlsym(libc_handle, "fchmod");
true_fchown = dlsym(libc_handle, "fchown");
true_fopen = dlsym(libc_handle, "fopen");
true_ftruncate = dlsym(libc_handle, "ftruncate");
true_lchown = dlsym(libc_handle, "lchown");
true_link = dlsym(libc_handle, "link");
true_mkdir = dlsym(libc_handle, "mkdir");
true_open = dlsym(libc_handle, "open");
true_rename = dlsym(libc_handle, "rename");
true_rmdir = dlsym(libc_handle, "rmdir");
true_symlink = dlsym(libc_handle, "symlink");
true_truncate = dlsym(libc_handle, "truncate");
true_unlink = dlsym(libc_handle, "unlink");

#if(GLIBC_MINOR >= 1)
true_creat64 = dlsym(libc_handle, "creat64");
true_fopen64 = dlsym(libc_handle, "fopen64");
true_ftruncate64 = dlsym(libc_handle, "ftruncate64");
true_open64 = dlsym(libc_handle, "open64");
true_truncate64 = dlsym(libc_handle, "truncate64");
#endif
/* Le ACL */
gridbox_aclsetup();


}
int chmod(const char *path, mode_t mode) {
int result;

printf("%s: chmod: %s %d\n", GRIDBOX_TITLE, path, mode);
result = true_chmod(path, mode);
return result;
}

int chown(const char *path, uid_t owner, gid_t group) {
int result;

printf("%s: chown: %s %d %d\n", GRIDBOX_TITLE, path, owner, group);
result = true_chown(path, owner, group);
return result;
}

int chroot(const char *path) {
int result;

printf("%s: chroot: %s\n", GRIDBOX_TITLE, path);
result = true_chroot(path);
return result;
}

int creat(const char *pathname, mode_t mode) {
/* Is it a system call? */
int result;

printf("%s: creat: %s %d\n", GRIDBOX_TITLE, pathname, mode);
result = true_creat(pathname, mode);
return result;
}

int fchmod(int filedes, mode_t mode) {
int result;

printf("%s: fchmod: %d %d\n", GRIDBOX_TITLE, filedes, mode);
result = true_fchmod(filedes, mode);
return result;
}

int fchown(int fd, uid_t owner, gid_t group) {
int result;

printf("%s: fchown: %d %d %d\n", GRIDBOX_TITLE, fd, owner, group);
result = true_fchown(fd, owner, group);
return result;
}

int check_fopen(const char *pathname, const char *mode);

FILE *fopen(const char *pathname, const char *mode) {
FILE *result;
int allowed = check_fopen(pathname, mode);

gridbox_log(allowed, "fopen", (char *)pathname);

if (allowed)
result = true_fopen(pathname,mode);
else
result = NULL;
return result;
}

int ftruncate(int fd, TRUNCATE_T length) {
int result;

printf("%s: ftruncate: %d %d\n", GRIDBOX_TITLE, fd, (int)length);
result = true_ftruncate(fd, length);
return result;
}

int lchown(const char *pathname, uid_t owner, gid_t group) {
/* Linux specific? */
int result;
int allowed = check_lchown(pathname, owner, group);

gridbox_log(allowed, "lchown", (char *)pathname);

if (allowed)
result = true_chown(pathname, owner, group);
else
result = -EPERM;
return result;
}

int link(const char *oldpath, const char *newpath) {
int result;

printf("%s: link: %s %s\n", GRIDBOX_TITLE, oldpath, newpath);
result = true_link(oldpath, newpath);
return result;
}

int mkdir(const char *pathname, mode_t mode) {
int result;
int allowed = check_mkdir(pathname, mode);

gridbox_log(allowed, "mkdir", (char *)pathname);

if (allowed)
result = true_mkdir(pathname, mode);
else
result = -EPERM;
return result;
}

int open(const char *pathname, int flags, ...) {
/* Eventually, there is a third parameter: it's mode_t mode */
va_list ap;
mode_t mode;
int result, allowed;

va_start(ap, flags);
mode = va_arg(ap, mode_t);
va_end(ap);

allowed = check_open(pathname, flags, mode);

gridbox_log(allowed, "open", (char *)pathname);

if (allowed)
result = true_open(pathname, flags, mode);
else
result = -EPERM;

return result;
}

int rename(const char *oldpath, const char *newpath) {
int result;

printf("%s: rename: %s %s\n", GRIDBOX_TITLE, oldpath, newpath);
result = true_rename(oldpath, newpath);
return result;
}

int rmdir(const char *pathname) {
int result;
int allowed = check_rmdir(pathname);

gridbox_log(allowed, "rmdir", (char *)pathname);

if (allowed)
result = true_rmdir(pathname);
else
result = -EPERM;
return result;
}

int symlink(const char *oldpath, const char *newpath) {
int result;

printf("%s: symlink: %s %s\n", GRIDBOX_TITLE, oldpath, newpath);
result = true_symlink(oldpath, newpath);
return result;
}

int truncate(const char *pathname, TRUNCATE_T length) {
int result;
int allowed = check_truncate(pathname, length);

gridbox_log(allowed, "truncate", (char *)pathname);

if (allowed)
result = true_truncate(pathname, length);
else
result = -EPERM;
return result;
}

int unlink(const char *pathname) {
int result;
int allowed = check_unlink(pathname);

gridbox_log(allowed, "unlink", (char *)pathname);

if (allowed)
result = true_unlink(pathname);
else
result = -EPERM;
return result;
}

#if(GLIBC_MINOR >= 1)

int creat64(const char *pathname, __mode_t mode) {
/* Is it a system call? */
int result;

printf("%s: creat64: %s %d\n", GRIDBOX_TITLE, pathname, mode);
result = true_creat64(pathname, mode);
return result;
}

int ftruncate64(int fd, __off64_t length) {
int result;

printf("%s: ftruncate64: %d %d\n", GRIDBOX_TITLE, fd, length);
result = true_ftruncate64(fd, length);
return result;
}

FILE *fopen64(const char *pathname, const char *mode) {
FILE *result;

printf("%s: fopen64: %s %s\n", GRIDBOX_TITLE, pathname, mode);
result = true_fopen(pathname,mode);
return result;
}

int open64(const char *pathname, int flags, ...) {
/* Eventually, there is a third parameter: it's mode_t mode */
va_list ap;
mode_t mode;
int result;

va_start(ap, flags);
mode = va_arg(ap, mode_t);
va_end(ap);

printf("%s: open64: %s %d %d\n", GRIDBOX_TITLE, path, flags, mode);
result = true_open64(pathname, flags, mode);
return result;
}

int truncate64(const char *path, __off64_t length) {
int result;

printf("%s: truncate64: %s %d\n", GRIDBOX_TITLE, path, length);
result = true_truncate64(path, length);
return result;
}

#endif /* GLIBC_MINOR >= 1 */

static int (*true_listen)(int s, int backlog);

int socket(int domain, int type, int protocol)
{
int result;

printf("%s: socket: %d %d %d\n", GRIDBOX_TITLE, domain, type, protocol);
result = true_socket(domain, type, protocol);
return result;
}

int connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen)
{
int result;
char addrstr[20];
struct sockaddr_in *addr;
int port;
char *address;
int allowed = check_connect(sockfd, serv_addr, addrlen);

addr = (struct sockaddr_in *)serv_addr;
port = htons(addr->sin_port);
address = inet_ntoa(addr->sin_addr);

sprintf(addrstr, "%s:%d", address, port);

gridbox_log(allowed, "connect", addrstr);

if (allowed)
result = true_connect(sockfd, serv_addr, addrlen);
else
result = -EPERM;
return result;
}

int bind(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen)
{
int result;
char addrstr[20];
struct sockaddr_in *addr;
int port;
char *address;
int allowed = check_bind(sockfd, serv_addr, addrlen);

addr = (struct sockaddr_in *)serv_addr;
port = htons(addr->sin_port);
address = inet_ntoa(addr->sin_addr);

sprintf(addrstr, "%s:%d", address, port);
gridbox_log(allowed, "bind", addrstr);


if (allowed)
result = true_bind(sockfd, serv_addr, addrlen);
else
result = -EPERM;
return result;
}

int listen(int s, int backlog)
{
int result;

printf("%s: listen: %d %d\n", GRIDBOX_TITLE, s, backlog);
result = true_listen(s, backlog);
return result;
}

int system(const char *command)
{
int result;
int allowed = check_system(command);

gridbox_log(allowed, "system", (char *)command);

if (allowed)
result = true_system(command);
else
result = -1;
return result;
}

دقت کنید مثلا RTLD_NEXT در هدر dlfcn.h تعریف شده اما نمیشاندش! و تابع void _init(void) هم که همون اررور multiple def رو میده.
واضح تر شد سوالم؟

sh4mid
پنج شنبه 12 فروردین 1389, 18:50 عصر
پیغام خطا رو کامل بگذارید اینجا
مشکل بخاطر اینه که RTLD_NEXT تو استاندارد Posix تعریف نشده باید دستی فعالش کنی
از این استفاده کن


#define _GNU_SOURCE
یا


-D_GNU_SOURCE رو تو Command-line استفاده کن

arashmidos2020
پنج شنبه 12 فروردین 1389, 19:38 عصر
/root/Desktop/ptraceWorking/gridboxBYc/libgridbox.c|70|multiple definition of `_init'|

/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/crti.o:/build/buildd/glibc-2.9/build-tree/i386-libc/csu/crti.S|15|first defined here|

libgridbox.c:(.text+0x1c)||undefined reference to `dlsym'|

اررور سوم رو از همه dlsym ها می گیره!
اگه می خواید بفرمایید کل پروژه رو بزارم

arashmidos2020
پنج شنبه 12 فروردین 1389, 20:48 عصر
خود پروژه رو گذاشتم اگه خواستید ببینیدش
http://barnamenevis.org/forum/showthread.php?t=212433

arashmidos2020
پنج شنبه 12 فروردین 1389, 22:05 عصر
پیغام خطا رو کامل بگذارید اینجا
مشکل بخاطر اینه که RTLD_NEXT تو استاندارد Posix تعریف نشده باید دستی فعالش کنی
از این استفاده کن


#define _GNU_SOURCEیا


-D_GNU_SOURCE رو تو Command-line استفاده کن



define رو گذاشتم نشد!میدونی اصلا هدرش اون بالا هست dlfcn اما هیچ کدوم از توابع و define هاشو نمی شناسه.اینم بگم هدرش تو usr/include/ هست.یعنی چه اتفاقی افتاده؟؟
ضمنا منظورتون رو از تو command line نفهمیدم.

sh4mid
پنج شنبه 12 فروردین 1389, 22:44 عصر
define را قبل
include<dlfcn> بذار
منظور از command-line اینه که وقتی می خواهی با gcc برنامتو compile کنی تو خط فرمان گزینه بالا رو بهش اضافه کنی بزن gcc -h دستت میاد چی میگم
از چه نسخه gcc و linux استفاده می کنی ؟ چه kernel؟ و این برنامه قراره چکار کنه ؟
کلش همون برنامه 17K هست؟

arashmidos2020
جمعه 13 فروردین 1389, 01:28 صبح
لینک اصلی رو هموم بالا دادم دیگه. اگه ببینید متوجه میشید چکار می خوام بکنم.
تشکر