Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
#1

Может ли третий проверка возвращаемого функцией значения влиять на результат линковки? - C++

12.03.2013, 01:38. Просмотров 668. Ответов 19
Метки нет (Все метки)

Не торопитесь с ответом. Я тоже так думал.
Кропаем dll:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//dllka.cpp
#include <unknwn.h>
void f(){
  
  //Размер взят от балды
  char x [23];
 
  //так ругается
  //if(memcmp(&x,&IID_IUnknown,2)); 
  
  //а так нет
  memcmp(&x,&IID_IUnknown,2); 
}
Bash
1
2
3
4
5
rem кропаем dll
g++ -c -DBUILD_DLL dllka.cpp
g++ -shared -o dllka.dll -Wl,--out-implib,libdllka.a dllka.o
del dllka.o libdllka.a
rem конец кропания dll
Нормально?
Теперь: код, понятно, искусственный. Реальный код много больше, я его просто упрощал до минимума чтобы лишь продемонстрировать ошибку в линковке. В чём же дело, друзья?

...А самое главное, ругается вот на эту фигню:
Bash
1
2
3
4
g++ -shared -o dllka.dll -Wl,--out-implib,libdllka.a dllka.o
Creating library file: libdllka.a
dllka.o:dllka.cpp:(.text+0x12): undefined reference to `IID_IUnknown'
collect2: ld returned 1 exit status
Ну это вообще вне моего понимания. Если он не может распознать IID_IUnknown, что же он её как-то выборочно не может распознать? То может то не может.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.03.2013, 01:38
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Может ли третий проверка возвращаемого функцией значения влиять на результат линковки? (C++):

Назначение возвращаемого значения функцией - C++
Уважаемые форумчане, помогите пожалуйста ответить на пару тройку вопросов:wall: 1.Поясните назначение возвращаемого значения функцией....

По ссылке на функцию получить тип возвращаемого этой функцией значения - C++
Существует задача следующего характера. Шаблон класса параметризуется ссылкой на функцию. Необходимо, чтобы один из членов класса имел тип,...

Почему тип входящего параметра функции может отличаться от типа возвращаемого значения? - C++
Зачем здесь указываеться другой тип данных: double &amp;change_it(int i); Весь код: using namespace std; double...

Сравнить значения двух массивов и вывести результат в третий массив - C++
Добрый день программисты и те кто любит пощёлкать клавишами. Есть такая задача. Нужно написать программку, которая сравнивала бы значения...

Постопределение возвращаемого функцией типа - C++
Суть проблемы: есть метод без аргументов, который в зависимости от флага должен возвращать либо тип T1, либо тип T2. Собственно, реализуемо...

может ли 64 битный windows как-то влиять на работу программы - C++
Народ подскажите может ли 64 битный windows как-то влият на работу программы.(которая выводит биты числа на экран два чила в двоичной...

19
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
12.03.2013, 01:44 #2
Цитата Сообщение от kravam Посмотреть сообщение
//так ругается
Цитата Сообщение от kravam Посмотреть сообщение
//а так нет
Цитата Сообщение от kravam Посмотреть сообщение
...А самое главное, ругается вот на эту фигню:
ещё раз - оно хоть раз слинковалось или вообще не линкуется?
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
12.03.2013, 01:57  [ТС] #3
конечно не слинковалось. Образовалось два файла *.o и *a, а dll нет; при такой ошибке линковщика
Bash
1
undefined reference to ...
Насколько я знаю dll или exe нет и быть не может. Надо из названия темы убрать слово "третий"
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
12.03.2013, 02:22 #4
попробуй прилинковать libuuid.a
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
12.03.2013, 11:24  [ТС] #5
Ладно, упростим себе жизнь, попробуем кропать чисто dll, без *.a:

C++
1
2
3
4
5
6
7
8
9
10
11
//dllka.cpp
#include <unknwn.h>
void f(){
  
  //Размер взят от балды
  char x [23];
 
  //так ругается
  if(memcmp(&x,&IID_IUnknown,2)); 
  
}
компилим:
Bash
1
2
g++ -c -DBUILD_DLL dllka.cpp
g++ -shared -o dllka.dll "E:\Dev_Cpp_nomingw\lib\libuuid.a" dllka.o
получаем ошибку при линковке:

Bash
1
2
3
g++ -shared -o dllka.dll "E:\Dev_Cpp_nomingw\lib\libuuid.a" dllka.o
dllka.o:dllka.cpp:(.text+0x12): undefined reference to `IID_IUnknown'
collect2: ld returned 1 exit status
Но это же ложь! Смотрим:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
nm dllka.o
00000000 b .bss
00000000 d .data
00000000 r .eh_frame
00000000 t .text
 
         //Вот идентификатор
         U _IID_IUnknown
 
 
00000000 T __Z1fv
         U _memcmp
и далее:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
nm "E:\Dev_Cpp_nomingw\lib\libuuid.a"
 
...
00000000 r .rdata
00000000 t .text
00000010 R _IID_IClassFactory
 
//И вот идентификатор!
00000000 R _IID_IUnknown
 
servprov-uuid.o:
00000000 b .bss
00000000 d .data
...
То есть _IID_IUnknown присутствует как в файле dllka.o, на базе которого я и строю *.dll, так и в libuuid.a, который я прилинковываю. Тем не менее, ничё не прилинковывается, сами видите

Добавлено через 14 минут
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Ещё упрощаем жизнь. Кропаем не dll, а exe:
C++
1
2
3
4
5
6
7
8
9
10
//dllka.cpp
#include <unknwn.h>
int main (){
  
  //Размер взят от балды
  char x [23];
 
  //так ругается
  if(memcmp(&x,&IID_IUnknown,2)); 
}
компилим:
Bash
1
2
g++ -c main.cpp
g++ -o main.exe "E:\Dev_Cpp_nomingw\lib\libuuid.a" main.o
Те же ошибки, _IID_IUnknown присутствует как в libuuid.a, так и в main.o

Добавлено через 13 минут
В MSVS на ура всё проходит...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "stdafx.h"
#include <unknwn.h>
 
 
int _tmain(int argc, _TCHAR* argv[])
{
        //Размер взят от балды
  char x [23];
 
  //так ругается
  if(memcmp(&x,&IID_IUnknown,2)); 
 
    return 0;
}
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
12.03.2013, 11:35 #6
C++
1
#include <unknwn.h>
может его как то отдельно нужно компилировать(или задать доп опции компилятору)

Добавлено через 9 минут
насколько я понял для g++ это нестандартный заголовок
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
12.03.2013, 11:37  [ТС] #7
Может быть. Но как правильно из *.h файла получить *.o файл, я не знаю...


Цитата Сообщение от XRuZzz Посмотреть сообщение
насколько я понял для g++ это нестандартный заголовок
Цитата Сообщение от XRuZzz Посмотреть сообщение
#include <unknwn.h>
Не знаю, что уж в нём нестандартного... Заголовок как заголовок, у меня сотня таких.
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
12.03.2013, 11:44 #8
вот например строки из unknwn.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
//////////////////////////////////////////////////////////////////
// IID_IUnknown and all other system IIDs are provided in UUID.LIB
// Link that library in with your proxies, clients and servers
//////////////////////////////////////////////////////////////////
 
#if (_MSC_VER >= 1100) && defined(__cplusplus) && !defined(CINTERFACE)
    EXTERN_C const IID IID_IUnknown;
    extern "C++"
    {
        MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
        IUnknown
        {
 
...
#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
    IUnknown
    {
то есть можно попробовать расставить нужные defin-ы перед include.

обратите внимание на комментарий перед условной компиляцией. по ходу надо прилинковать UUID.LIB
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
12.03.2013, 11:54  [ТС] #9
Цитата Сообщение от XRuZzz Посмотреть сообщение
то есть можно попробовать расставить нужные defin-ы перед include.
Да не нужно. Необходимые define и так расставлены. Если бы это было не так, идентификатора IID_IUnknown просто напросто бы не было в получившемся файле *.o. (препроцессор не включил бы его в сырец, который подаётся на вход компилятору).А он там есть.

Цитата Сообщение от XRuZzz Посмотреть сообщение
обратите внимание на комментарий перед условной компиляцией. по ходу надо прилинковать UUID.LIB
что я и делаю:
Bash
1
g++ -o main.exe "E:\Dev_Cpp_nomingw\lib\libuuid.a" main.o
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
12.03.2013, 12:00 #10
не понимаю откуда в g++ возьмётся define _MSC_VER
а если линковать файл студии в g++
C:\Program Files\Microsoft Visual Studio 8\VC\lib\uuid.lib
?
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
12.03.2013, 12:05  [ТС] #11
Вот мой файл unknwn.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#ifndef COM_NO_WINDOWS_H
#include <windows.h>
#endif
 
#ifndef _UNKNWN_H
#define _UNKNWN_H
#if __GNUC__ >=3
#pragma GCC system_header
#endif
 
#ifdef __cplusplus
extern "C"{
#endif
#include <objfwd.h>
#include <wtypes.h>
 
void * __RPC_USER MIDL_user_allocate(size_t);
void __RPC_USER MIDL_user_free(void*);
EXTERN_C const IID IID_IUnknown;
EXTERN_C const IID IID_IClassFactory;
#ifndef __IUnknown_INTERFACE_DEFINED__
#define __IUnknown_INTERFACE_DEFINED__
#define INTERFACE IUnknown
DECLARE_INTERFACE(IUnknown)
{
    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;
};
#undef INTERFACE
typedef IUnknown *LPUNKNOWN;
#endif
#ifndef __IClassFactory_INTERFACE_DEFINED__
#define __IClassFactory_INTERFACE_DEFINED__
#define INTERFACE IClassFactory
DECLARE_INTERFACE_(IClassFactory,IUnknown)
{
    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;
    STDMETHOD(CreateInstance)(THIS_ LPUNKNOWN,REFIID,PVOID*) PURE;
    STDMETHOD(LockServer)(THIS_ BOOL) PURE;
};
#undef INTERFACE
typedef IClassFactory *LPCLASSFACTORY;
#endif
HRESULT STDMETHODCALLTYPE IUnknown_QueryInterface_Proxy(IUnknown*,REFIID,void**);
void __RPC_STUB IUnknown_QueryInterface_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);
ULONG STDMETHODCALLTYPE IUnknown_AddRef_Proxy(IUnknown*);
void __RPC_STUB IUnknown_AddRef_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);
ULONG STDMETHODCALLTYPE IUnknown_Release_Proxy(IUnknown*);
void __RPC_STUB IUnknown_Release_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);
HRESULT STDMETHODCALLTYPE IClassFactory_RemoteCreateInstance_Proxy(IClassFactory*,REFIID,IUnknown**);
void __RPC_STUB IClassFactory_RemoteCreateInstance_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);
HRESULT __stdcall IClassFactory_RemoteLockServer_Proxy(IClassFactory*,BOOL);
void __RPC_STUB IClassFactory_RemoteLockServer_Stub(LPRPCSTUBBUFFER,LPRPCCHANNELBUFFER,PRPC_MESSAGE,PDWORD);
HRESULT STDMETHODCALLTYPE IClassFactory_CreateInstance_Proxy(IClassFactory*,IUnknown*,REFIID,void**);
HRESULT STDMETHODCALLTYPE IClassFactory_CreateInstance_Stub(IClassFactory*,REFIID,IUnknown**);
HRESULT STDMETHODCALLTYPE IClassFactory_LockServer_Proxy(IClassFactory*,BOOL);
HRESULT STDMETHODCALLTYPE IClassFactory_LockServer_Stub(IClassFactory*,BOOL);
 
#if (!defined (__cplusplus) || defined (CINTERFACE)) \
    && defined (COBJMACROS)
#define IUnknown_QueryInterface(T,r,O) (T)->lpVtbl->QueryInterface(T,r,O)
#define IUnknown_AddRef(T) (T)->lpVtbl->AddRef(T)
#define IUnknown_Release(T) (T)->lpVtbl->Release(T)
#define IClassFactory_QueryInterface(T,r,O) (T)->lpVtbl->QueryInterface(T,r,O)
#define IClassFactory_AddRef(T) (T)->lpVtbl->AddRef(T)
#define IClassFactory_Release(T) (T)->lpVtbl->Release(T)
#define IClassFactory_CreateInstance(T,p,r,O) (T)->lpVtbl->CreateInstance(T,p,r,O)
#define IClassFactory_LockServer(T,f) (T)->lpVtbl->LockServer(T,f)
#endif /* COBJMACROS */
#ifdef __cplusplus
}
#endif
#endif
Больше идентификатор IID_IUnknown НИГДЕ, ни в одном из файлов*.h не упоминается.
И чё мне делать теперь?
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
12.03.2013, 12:16 #12
ну если немного расшифровать строку
C++
1
EXTERN_C const IID IID_IUnknown;
то получится
C++
1
extern "C" const GUID IID_IUnknown;
дальше лень копаться )

где то GUID должна быть определена скомпилирована и прилинкована
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
12.03.2013, 12:28  [ТС] #13
Вот стркутура GUID
C++
1
2
3
4
5
6
7
//winnt.h
typedef struct _GUID {
    unsigned long  Data1;
    unsigned short Data2;
    unsigned short Data3;
    unsigned char  Data4[8];
} GUID, *REFGUID, *LPGUID;
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
12.03.2013, 12:59 #14
зачем вам проверять
C++
1
if (memcmp ...
на g++
?

Добавлено через 1 минуту
как это поможет пользователю?

Добавлено через 2 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//dllka.cpp
#include <unknwn.h>
void f(){
  
  //Размер взят от балды
  char x [23];
 
  //так ругается
  //if(memcmp(&x,&IID_IUnknown,2)); 
  
  //а так нет
  memcmp(&x,&IID_IUnknown,2); 
}
тут скорее всего при оптимизации компилятор выкидывает сравнение memcmp(&x,&IID_IUnknown,2);

может попробовать с опцией -O0?

Добавлено через 18 минут
поздравляю вам удалось заставить меня скомпилить ваш пример.

это удаётся только если задать линкеру опцию -luuid
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,493
12.03.2013, 13:01  [ТС] #15
Цитата Сообщение от XRuZzz Посмотреть сообщение
зачем вам проверять
Цитата Сообщение от XRuZzz Посмотреть сообщение
как это поможет пользователю?
Позвольте мне этого не объяснять. Я в первом сообщении сказал, что код утрированный. Если я выложу неутрированный, Вы, извините за выражение, закалебётесь пыль глотать его разбирать. В неутрированном (кстати), присутствует такая строка:

C++
1
2
  if(::memcmp(&riid,&IID_IUnknown,sizeof(GUID)) == 0) 
    //Тут некоторо едействие
Так что проверку условия я ввёл не от балды.

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

тут скорее всего при оптимизации компилятор выкидывает сравнение memcmp(&x,&IID_IUnknown,2);
Там идентификатора IID_IUnknown в *.o файле просто-напросто нет. Я потом уже это обнаружил, но не стал сюда писать, сконцетрировался на другом коде. (Поэтому линковщик не встречает в *.o файле идентификатор IID_IUnknown и, поэтому не ругается.) Почему нет- это второй вопрос. Если это оптимизация, то ну его на фиг такую оптимизацию, не знаю в общем.

Щас возвернёмся к коду:
C++
1
2
3
4
5
6
7
8
9
10
//dllka.cpp
#include <unknwn.h>
int main (){
  
  //Размер взят от балды
  char x [23];
 
  //так ругается
  if(memcmp(x,&IID_IUnknown,2)); 
}
НУ даже пусть мой unknwn.h отличается от вашего (у меня есть оба *.h, но понятно, я работаю с "родным", который и показал), но идентификатор-то IID_IUnknown присутствует как в *.o файле, так и в *.a!


поздравляю вам удалось заставить меня скомпилить ваш пример.
это удаётся только если задать линкеру опцию -luuid
Да я уж и с опцией и всяко компилил, я же писал. Дайте командную строку, а?
0
12.03.2013, 13:01
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.03.2013, 13:01
Привет! Вот еще темы с ответами:

Сохранение возвращаемого функцией значения - MS Excel
Ещё одна проблема с которой столкнулся, моя програмка создает заказы и сохраняет на отдельном лсите, при сохранении заказа макрос копирует...

Укажите тип возвращаемого функцией значения - Python
Для каждой функции в выражении print(list(map(int, input().split()))) укажите тип возвращаемого значения (результата)(list; map; NoneType;...

Присваивание переменной класса значения, возвращаемого функцией - PHP ООП
Здравствуйте. Помогите понять следующую вещь... Допустим есть класс core с функцией get_db_info. Если я её вызову так: $info =...

Тип возвращаемого функцией значения, для вставки в ComboBox - C++ Builder
Какого типа должно быть возвращаемое значение, если я получаю от функции список строк для вставки в объекты TComboBox или TTabControl? ...


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

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

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