Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
быдлокодер
1718 / 905 / 106
Регистрация: 04.06.2008
Сообщений: 5,612
1

Как узнать, какой функции какой файл *.a соответсвует?

15.02.2012, 23:44. Просмотров 1664. Ответов 9
Метки нет (Все метки)

Друзья! Работаю с mingw, вот там надо так: если, допустим, вызываешь API- функцию, то надо подключать соответствующую библиотеку (?), делается это ключом линкёра примерно так:

-lwww файл

Эта команда значит, что libwww.a, находящийся в папке lib, подключится к проекту и что это значит Я НЕ ЗНАЮ. Да и честно говоря, как программиста приложений меня не должно это волновать.

Но иногда я не знал, какой функции какой файл *.a соответсвует- инет выручал, как правило запрос
Bash
1
 [Linker error] undefined reference to `имя_функции'
уже кто-то делал до меня и уже кто-то кому-топодсказывал ключ и всё было ОК. Но чем дальше в лес, тем больше дров, функции, используемые мною уже всё менее и менее употребимы- то есть никто с таким не сталкивался и подсказки в инете я найти не могу. Должен же быть способ узнать, есть ли среди набора файлов *.a нужный тебе или нет?

+++++++++++++++++++++++++++++++++++++++

Проведём аналогию с хидерами. Допустим, мне нужно узнать, в каком хидере объявлена функция
CreateDirectory, командую в папке с хидерами
Bash
1
FINDSTR /S /I "CreateDirectoryA" *h*> CreateDirectory.txt
и получаю CreateDirectory.txt такого содержания:

Bash
1
2
3
4
winbase.h:WINBASEAPI BOOL WINAPI CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES);
winbase.h:#define CreateDirectory CreateDirectoryA
wininet.h:BOOL WINAPI FtpCreateDirectoryA(HINTERNET,LPCSTR);
wininet.h:#define FtpCreateDirectory FtpCreateDirectoryA
Всё, как на ладони. Хотелось бы подобное проедлывать с *.a файлами, спасибо, кто откликнется!

Добавлено через 1 час 32 минуты
Ну и сразу же, чтобы не кропать лишнюю тему- а можно ли самому скропать *.a файл на основе имеющейся dll-ки, если функция, которую линкё не видит, есть в этой dll-ке? То есть я качнул с одно места такие ресурсы:

x.h
libx.a
x.dll

подключал хидер и комплиил -lx, всё было нормально, пока линкёр не ругнулся на одну из функций (в хидере обхявлена, я прошерстилд dll-ку- она и там присутствует! Значит, дело в промежуточном звене libx.a; я не знаю его формата но если там какие-то адреса на функции, может его можно скропать на основе имеющегося x.dll- кропаем же мы экзешники!!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.02.2012, 23:44
Ответы с готовыми решениями:

Как узнать какой Edit активный
Есть два Editта мне нужно узнать какой Edit сейчас активный (активный Edit то в который вводится...

Как узнать какой компонент в фокусе
Всем доброго времени суток. Кто может подсказать как определить какой компонент сейчас находится в...

Как узнать какой процесс какой файл использует?
Здравствуйте, подскажите как можно узнать какой процесс какой файл использует? Преподаватель...

Как в WM_COMMAND узнать, по какой из кнопок произошел клик?
Если у меня в клиентской области расположены девять дочерних окон("Button"), как в WM_COMMAND...

9
Каратель
Эксперт С++
6593 / 4014 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
15.02.2012, 23:50 2
если речь о функиях ВинАПИ то на мсдн можно посмотреть к какому файлу *.a(*.lib) относится
0
быдлокодер
1718 / 905 / 106
Регистрация: 04.06.2008
Сообщений: 5,612
15.02.2012, 23:53  [ТС] 3
Я не раз уж смотрел, в том-то и дело, что не WinAPI, сторонняя библиотека. Написал бы какая- да интересует ОБЩИЙ принцип.
Ну и второй вопрос встал как нельзя остро- файл *.a я узнал но он не рабочий, что ли... Как на освое dll сделать .a файл?
0
Каратель
Эксперт С++
6593 / 4014 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
16.02.2012, 01:37 4
общего принципа здесь нет, такие вещи указывают в документации к библиотеке которая как правило есть на сайте разработчиков
0
быдлокодер
1718 / 905 / 106
Регистрация: 04.06.2008
Сообщений: 5,612
16.02.2012, 14:38  [ТС] 5
А программно если? утилита reimp:
C++
1
reimp.exe -s x.dll
Выдаёт на-гора список символов " -s, --dump-symbols"
Надо просто найти такую же утилиту, но для *.a файлов. Я бы и сам смог написать, знай формат *.a файла и дело сделано, считай.
0
Эксперт С++
3210 / 1459 / 73
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
16.02.2012, 18:01 6
grep`ом
1
быдлокодер
1718 / 905 / 106
Регистрация: 04.06.2008
Сообщений: 5,612
17.02.2012, 00:52  [ТС] 7
Я нашёл такое решение: во-первых, надо воспользоваться утилитой nm, она
C++
1
nm libfail.a
Выводит символы из *.a файлов в удобочитаемом виде. Их нужно анализировать на предмет нужной строки и это не конечное решение- всё же простыню читаь не очень удобно- и как быть если файлов много? А вот для решения этих вопросо я накропал очередной нетленный проект, за который всё человечество закалебётся со сной расплачиваться! Компилим исходники, в папку с экзешником кидаем nm (прилагается и балдеем)

Чувствительна к регистрам, кроме функций можно искать вообще строки;
Принцип: файлы*.a "пропускаюются" через утилиту nm, которая кропает текстовый файлы с символами, как ксказано у ней в helpe. Программно в этих файлах ищется нужная строка.

Если указываешь папку то файлы *.a ищутся в ней РЕКУРСИВНО

nm может на что-то ругнуться (некорректный файл); если этих надписей видеть не хотим, отписываемся, я кину прогу для того, чтобы вообще убирать консольное окно (то есть nm будет работать как бы фоном и никаких надписей касающихся непосредсовенно ругани nm вы не увидите)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <windows.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <vector>
#include <conio.h>
#include <iostream>
#include <iterator>
#include <fstream>
#include "funktsii.h"
using namespace std;
 
 
//Это понятно, что такое- вектор строк имён файлов с расширением "a"
vector <string> imena_failov_a;  
 
//Имя функции
string ima_funktsi;
 
string temp_;
 
 
void interfeis ();
int main () {
 SetConsoleCP (1251);
 SetConsoleOutputCP (1251);
 
 //Тут будут аимнеа файлов, в которых упоминается нужная функция
 vector <string> imena_failov_s_funktsiei;
 
 char ima_papki [MAX_PATH];
 
 
 interfeis ();
 
 //ПРверим, с чем работаем- с папкой или с файлом, если с папкой- заполним её 
 //сответсвующим содержаниема
 if (!(imena_failov_a.size())) {
  imena_failov_a= GetFileList (strcpy (ima_papki, temp_.c_str()), (LPTSTR)"a", (LPTSTR)"A");
  if (!(imena_failov_a.size())) {
   printf ("пОхоже, что таких файлов нет!");
   getchar ();
   return 1;
  }
 } 
 
 
 ifstream iff;
 //Погнали работать
 for (int i= 0; i< imena_failov_a.size(); i++) {
  string str;
 
  char komanda [MAX_PATH]= "nm ";
  strcat (komanda, imena_failov_a[i].c_str());
  strcat (komanda, ">> temp_f.txt");
  system (komanda);
  iff.open("temp_f.txt");
  cout<<"проверяем "<< imena_failov_a [i]<< endl;
  while(getline(iff, str)) {
   if (str.find(ima_funktsi)!=string::npos) {
    imena_failov_s_funktsiei.push_back (imena_failov_a[i]);
    break;
   }
  }
  iff.close ();
  if (!DeleteFile ("temp_f.txt")) {
   Sleep (1000);
   if (!DeleteFile ("temp_f.txt")) {
    printf ("Чё-то не удаётся удалить ненужый файл\n");
    getchar ();
    return 1;
   }
  }
 }
 
 if (!(imena_failov_s_funktsiei.size())) 
  cout<< "Чё-то ничё не удалось найти"<< endl; 
 else {
  cout<< "\n+++++++++++++++++++++\n\nЭто: "<< ima_funktsi<<endl<<"Упоминается в файлах:\n"<<endl;
  copy (imena_failov_s_funktsiei.begin(), imena_failov_s_funktsiei.end(), ostream_iterator<string>(cout, "\n"));
 }
 fflush (stdin);
 getchar ();
  
 return 0;
}
 
void interfeis () {
 char temp;
 printf ("Ты будешь работать с одним файлом или с несолькими (1- один файл, 0- несколько)\n");
 do {
  temp= getch ();
 }
 while (temp!= '1' && temp!= '0');
 
 if (temp== '1') {
  printf ("Вводи имя файла\n"); 
  cin>> temp_;
  imena_failov_a.push_back (temp_);
 }
 else { 
  printf ("Вводи имя папки, если текущая- вводи точку, родительская- две точки, всё, как положено\n"); 
  cin>> temp_;
  
  //Уберём слэши с конца, если есть
  string::iterator it= temp_.end();
 
  while (*--it== '\\');
   it++;
 
  temp_.erase (it, temp_.end());
 
 }
 
 printf ("А теперь вводи имя функции, упоминание о которой хочешь встретить в *.a файле\n"); 
 cin>> ima_funktsi;
 
};

файл "funktsii.h"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <string>
using namespace std;
 
 
//Рекурсивно возвращает  имена всех *.a файлов
vector <string> GetFileList(LPTSTR sPath, LPTSTR sExt, LPTSTR sEXT) {
 
 static vector <string> te;
 
 string temp;
 
 
 WIN32_FIND_DATA pFILEDATA;
 
 HANDLE hFile = FindFirstFile(strcat(sPath,"\\*.*"),&pFILEDATA);
 
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!Необходимо именно здесь прописывать длину пути!!!!!!!!!!!!!!!!!!!!!!!
 sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0';
//Если пропишем после if (как предлагает Юра), то тогда, если вдруг натыкаемся на системную директорию
// или файл, то FindFirstFile возвращает -1. Следовательно, всё, что выплнняется по условию
//(hFile!=INVALID_HANDLE_VALUE) не выолнится и в частности, не будет поставлен конец строки!
//А это значит, что по выходу из  рекурсивной функции GetFileList в том месте, где мы восстанавливаем
//Длину, она будет восстановлена неправильно
 
 if (hFile!=INVALID_HANDLE_VALUE)    {
  char * chBuf;
  //sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0';
  do {
   //Пропускаем . и ..
   if (strlen(pFILEDATA.cFileName) == 1 &&  strchr(pFILEDATA.cFileName,'.') !=NULL)
    if (FindNextFile(hFile,&pFILEDATA) == 0)
      break;
   if (strlen(pFILEDATA.cFileName) == 2 && strstr(pFILEDATA.cFileName,"..") !=NULL)
    if(FindNextFile(hFile,&pFILEDATA) == 0)
      break;
     //Если нашли директорию, запускаем поиск в ней рекурсивный поиск
   if(pFILEDATA.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
     GetFileList(strcat(sPath,pFILEDATA.cFileName), sExt, sEXT);
 
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!оБЯЗАТЕЛЬН востанавливать дллину пути................................     
     sPath[strlen(sPath) - strlen(pFILEDATA.cFileName)- 1] = '\0';
   }
   else {
    //Проверяем на соотвествие sExt расширения pFILEDATA.cFileName
    //Смотрим здесь
    if((chBuf = strrchr(pFILEDATA.cFileName,'.'))) {
     if((!strcmp(chBuf + 1,sExt))|| (!strcmp(chBuf + 1,sEXT)))       
      te.push_back (temp= string (sPath)+ string (pFILEDATA.cFileName));
    }
   }
  }
  while (FindNextFile(hFile,&pFILEDATA));
 }
 return te;
 
}
0
Вложения
Тип файла: rar nm.rar (251.4 Кб, 9 просмотров)
Каратель
Эксперт С++
6593 / 4014 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
17.02.2012, 01:45 8
Цитата Сообщение от kravam Посмотреть сообщение
fflush (stdin);
так делать нельзя, это UB
1
быдлокодер
1718 / 905 / 106
Регистрация: 04.06.2008
Сообщений: 5,612
17.02.2012, 18:09  [ТС] 9
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <windows.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <vector>
#include <conio.h>
#include <iostream>
#include <iterator>
#include <fstream>
#include "funktsii.h"
using namespace std;
 
//Это понятно, что такое- вектор строк имён файлов с расширением "lib"
vector <string> imena_failov_lib;  
 
//Имя функции
//string ima_funktsi;
string ima_funktsi= "_strcat_s";
 
string temp_;
 
void interfeis ();
int main () {
 SetConsoleCP (1251);
 SetConsoleOutputCP (1251);
 
 //Тут будут имнеа файлов, в которых упоминается нужная функция
 vector <string> imena_failov_s_funktsiei;
 
 char ima_papki [MAX_PATH];
 
  //interfeis ();
 
 //ПРверим, с чем работаем- с папкой или с файлом, если с папкой- заполним её 
 //сответсвующим содержаниема
 if (!(imena_failov_lib.size())) {
//  imena_failov_lib= GetFileList (strcpy (ima_papki, temp_.c_str()), (LPTSTR)"lib", (LPTSTR)"LIB");
  imena_failov_lib= GetFileList (strcpy (ima_papki, "E:\\Microsoft_Visual_Studio_9.0"), (LPTSTR)"lib", (LPTSTR)"LIB");
  if (!(imena_failov_lib.size())) {
   printf ("пОхоже, что таких файлов нет!");
   getchar ();
   return 1;
  }
 } 
  
 ifstream iff;
 //Погнали работать
 for (int i= 0; i< imena_failov_lib.size(); i++) {
  string str;
 
  char komanda [MAX_PATH]= "reimp -s \"";
  strcat (komanda, imena_failov_lib[i].c_str());
  strcat (komanda, "\"");
  strcat (komanda, ">> temp_f.txt");
  system (komanda);
  iff.open("temp_f.txt");
  cout<<"проверяем "<< imena_failov_lib [i]<< endl;
  while(getline(iff, str)) {
   if (str.find(ima_funktsi)!=string::npos) {
    imena_failov_s_funktsiei.push_back (imena_failov_lib[i]);
    break;
   }
  }
  iff.close ();
  if (!DeleteFile ("temp_f.txt")) {
   Sleep (1000);
   if (!DeleteFile ("temp_f.txt")) {
    printf ("Чё-то не удаётся удалить ненужый файл\n");
    getchar ();
    return 1;
   }
  }
 }
 
 if (!(imena_failov_s_funktsiei.size())) 
  cout<< "Чё-то ничё не удалось найти"<< endl; 
 else {
  cout<< "\n+++++++++++++++++++++\n\nЭто: "<< ima_funktsi<<endl<<"Упоминается в файлах:\n"<<endl;
  copy (imena_failov_s_funktsiei.begin(), imena_failov_s_funktsiei.end(), ostream_iterator<string>(cout, "\n"));
 }
 fflush (stdin);
 getchar ();
  
 return 0;
}
 
void interfeis () {
 char temp;
 printf ("Ты будешь работать с одним файлом или с несолькими (1- один файл, 0- несколько)\n");
 do {
  temp= getch ();
 }
 while (temp!= '1' && temp!= '0');
 
 if (temp== '1') {
  printf ("Вводи имя файла\n"); 
  cin>> temp_;
  imena_failov_lib.push_back (temp_);
 }
 else { 
  printf ("Вводи имя папки, если текущая- вводи точку, родительская- две точки, всё, как положено\n"); 
  cin>> temp_;
  
  //Уберём слэши с конца, если есть
  string::iterator it= temp_.end();
 
  while (*--it== '\\');
   it++;
 
  temp_.erase (it, temp_.end());
 
 }
 
 printf ("А теперь вводи имя функции, упоминание о которой хочешь встретить в *.lib файле\n"); 
 cin>> ima_funktsi;
 
};
Крайне важно! В первом посте допущена грубейшая ошибка. В функции GetFileList объявлен локальный вектор строк, но он должен быть СТАТИЧЕСКИМ. Эта функция возвращает этот вектор (полные имена в файлов) и если он будет локальным, то в функцию main вернётся вектор из строк, сформированных только при ПЕРВОМ вызове GetFileList. Пожалуйста поправьте!

То есть
C++
1
vector <string> te;
Надо заменить на
C++
1
static vector <string> te;
0
Вложения
Тип файла: rar reimp.rar (95.4 Кб, 11 просмотров)
быдлокодер
1718 / 905 / 106
Регистрация: 04.06.2008
Сообщений: 5,612
17.02.2012, 18:25  [ТС] 10
А я чё хотел сказать-то- если немного изменить код (как я), и и спользовать утилиту reimp.exe (прилагается) то ту же операцию можно будет проделывать и с файлами *.lib; а
C++
1
 static vector <string> te;
надо объявлять не в первом посте а в седьмом

Добавлено через 14 минут
А ещё там при формировании команды надо полное имя пути файла заключить в кавычки, вот так то есть надо писать:
C++
1
2
3
  char komanda [MAX_PATH]= "nm \"";
  strcat (komanda, imena_failov_a[i].c_str());
  strcat (komanda, "\"");
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.02.2012, 18:25

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Как узнать, какой файл *.a указывать в командной строке линкёра (компилятор g++)?
Друзья! Сейчас я делаю так. Допустим, линкёр выдаёт ошибку: undefined reference to...

Как узнать в какой ОС запускается программа?
Как узнать в какой ОС запускается программа? И уже дальше делать то или иное в зависимости от ОС.

С помощью какой функции загрузить файл
Во общем на заголовок вопрос, если есть возможность то с примером

Как узнать какой тип у шаблонного класса?
Есть класс с шаблонным массивом: template&lt;class T&gt; class cl1 { private: T mas; И метод,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.