Ошибка unresolved external builder c

Unresolved external

The unresolved external in your case, seems to be because the compiler is unable to find the path to the package data. You should find out if:

  • The path exists in the compiler search path list.
  • The package exists in the default package directory.

If one of them is true then the path isn’t the problem. However as Riho also mentions this is the most likely cause for the problem. The Embarcadero documentation wiki states the following about the unresolved external error:

The named symbol is referenced in the given module but is not defined anywhere in the set of object files and libraries included in the link. Check to make sure the symbol is spelled correctly.

You will usually see this error from the linker for C or C++ symbols if any of the following occur:

  • You did not properly match a symbol’s declarations of __pascal and __cdecl types in different source files.
  • You have omitted the name of an object file your program needs. You need to manually add all required packages to the Requires list.
  • You did not link in the emulation library.

If you are linking C++ code with C modules, you might have forgotten to wrap C external declarations in extern “C”.

You could also have a case mismatch between two symbols.

Source: Unresolved external ‘symbol’ referenced from ‘module’.

Since it seems from the — although altered class names — it is not the case of a misspelling. You also state that you have added the package to the requires list so we rule out this as well. Since you are not linking to C modules we can omit that part as well. So it points to problems with the directory.

About the other questions

Your questions are all really interesting and many of the questions are questions I my self has been looking for answers for when I started developing packages and components for C++ Builder.

Are packages reliable using C++?

Packages are a fine solution to use for C++ Builder, Both C++ Builder is built to support packages and the Pascal written VCL framework. This means that certain implementations are different in C++ Builder than other compilers. This is a necessity to keep the language compatible with its Delphi sibling. For this reason you can use packages in C++ Builder almost as easily as if using Delphi.

Is linking to the first package by adding a reference to its BPI correct?

To start with the second part of your question here, using a lib file makes your package larger simply because it is using static linking — so your guess is correct. Now back to the first part of the question, linking to a package is fine by adding a reference to its BPI. But you do need to make sure that the path variable has been set correctly as Riho suggests in his answer.

Personally I always make sure to my packages to the proper directories in your users folder, the location of this is depending on your Delphi version and operating system version. As far as I recall it is under the Document and Settingsall usersshared documentsRad studio(version number)Packages but I could be mistaken about that.

Can we use the PACKAGE directive only on TObject-derived classes?

The PACKAGE macro is resolved into __declspec(package), you can compare it to __declspec(dllexport). The difference between these is that package is used when declared in a package, and dllexport is used when declared in a DLL. There is a topic about this on the official embarcadero forums titled __declspec(package) vs __declspec(dllexport). The author of the original post, also asks your exact question about this, but unfortunately that part of the question is unanswered.

I have a theory however, and I must emphasize that it is nothing more than a theory. Remy Lebeau writes as a response to the question in the forum post:

__declspec(dllexport) can be used for plain functions, data variables, and
non-VCL classes, and can be used in plain DLLs. __declspec(package) is
used for VCL components, and can only be used with packages.

So from reading his response it seems to me that package is simply exporting the class, just like dllexport does. And since dllexport as far as I can read from his response is to be used in plain DLLs only you have to use the package for exporting (even) non VCL classes from a package.

What is interesting about all this, is that a package is essentially a DLL as far as I recall, but I must admit I can’t find or remember the source of that information so take with a grain of salt.

Is splitting code into packages the best way to achieve the goal of isolating code?

Packages have some very prominent strengths when creating reusable components for the VCL. Obviously using packages limits the user to use either C++Builder or Delphi, but for components written to take advantage of the VCL framework it’s an excellent choice. Properly written packages can ease the reusability of components, and I believe it is the preferred method of distributing components for the VCL.

However if your code does not take advantage of the VCL framework in any way, I would consider using an ordinary library, either static or dynamic, simply to create a more cross compiler friendly approach.

Whether there are any better approach to isolating your code, really depends on the project you are working on. I like to keep code that communicates through use of VCL classes in packages, but code that does not require use of any VCL classes in regular libraries. Keep in mind though that you can easily use VCL classes in a DLL but you need to handle special cases if you choose to export functions with VCL String classes as parameters or return values.

Any general words of advice?

I’m not the most experienced developer of packages myself, but I have found that disabling runtime linking often solves a lot of my problems, while it is somewhat trivial to fix any problems for your own code, you can often run into 3rd party components that have trouble dealing with this. Having said that, I’m not a fan of distributing my packages along with my application as is required in this case. But to be honest that is a matter of taste.

Personally I found it difficult to find some proper answers to many of my questions, when I started creating components and packages. The official helpfile is not the most informative on the matter, but looking through the VCL source code, will often give you the best answer to your question. Besides there is a few other websites that can provide help, many of the sites are targeting Delphi though, but this you have to get used to though.

Delphi Wikia has some good articles about creating components, in particular Creating Components and Creating Packages There is also BCB Journal which is one of the few C++ Builder specific sites, it has some fine articles and an acceptable forum. The Delphi pages at About.com is also a good source of information, I’ve found lots of good hints and nice to knows there, in particular: Creating Custom Delphi Components — Inside and Out.

64K

26 ноября 2010 года

Niakita

3 / / 25.11.2010

Код:

[ILINK32 Warning] Warning: Public symbol ‘_Form1’ defined in both module C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGUNIT2.OBJ and C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGUNIT1.OBJ

решение откапал здесь

Цитата:

;)Похожая ситуация, тоже три класса, один, условно говоря, основной (Назовем его А ) и два дополнительных TPlayThread , FlashIO .
Когда в основном классе А, классы TPlayThread , TFlashIO были объявлены в .cpp файле (TPlayThread*PlayThread, TFlashIO*FlashIO), всё было ОК, кроме невозможности обращения к методам FlashIO из PlayThread. Всё работало только из класса А.
Я перенёс объявления в h файл соответствующего класса, т.е. в FlashIO.h объявлено TFlashIO*FlashIO. Теперь все друг друга видят, но линкер ругается:

CollapsedExpandedWrap enabledWrap disabled

ILINK32 Warning] Warning: Public symbol ‘_FlashIO’ defined in both module D:PROJECTSDICPCDICDEBUGUPLAYTHREAD.OBJ and D:PROJECTSDICPCDICDEBUGUDIC.OBJ

[ILINK32 Warning] Warning: Public symbol ‘_FlashIO’ defined in both module D:PROJECTSDICPCDICDEBUGUPLAYTHREAD.OBJ and D:PROJECTSDICPCDICDEBUGUFLASHIO.OBJ

[ILINK32 Warning] Warning: Public symbol ‘_FlashIO’ defined in both module D:PROJECTSDICPCDICDEBUGUDIC.OBJ and D:PROJECTSDICPCDICDEBUGUFLASHIO.OBJ

Предположу, что из за взаимного перекрёстного включения h файлов, но если этого не делать, то снова кто то, что то не видит…

Цитата:

:cool:Ну так убери из заголовочного файла определение переменных. Или добавь к ним extern.
Надо ж хотя б немножко понимать инструмент, которым пользуешься.

кратенько про всякие там штуки:

Unresolved external — это сообщение линкера, означает, что в исходниках используется функция, которой нет в подключенных библиотеках и он не знает, что прилинковывать.

Слово «extern» в си означает, что переменная описана где-то в другом модуле, а в текущем описывается просто ссылка, чтобы ей можно было пользоваться.

это взял тут

Для тех кто на майле не зареган вот текст полностью:

Нашёл решение — точнее помогли в сообществе «Программирование» — на майл ру
————————————————————————-
Для тех кто там незареган вот текст всего что написано по ссылке:

Цитата:

:Unresolved external — Ошибка при компиляции
C++Builder 2007

при компиляции небольшой программы компилятор выдаёт вот такую бредятину:

[ILINK32 Error] Error: Unresolved external ‘_Form2’ referenced from C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGPROJECT1.OBJ

[ILINK32 Error] Error: Unresolved external ‘__fastcall TForm2::FormStartDock(System::TObject *, Controls::TDragDockObject *&)’ referenced from C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGUNIT2.OBJ

[ILINK32 Error] Error: Unresolved external ‘__fastcall TForm2::FormDockDrop(System::TObject *, Controls::TDragDockObject *, int, int)’ referenced from C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGUNIT2.OBJ

[ILINK32 Warning] Warning: Public symbol ‘_Form1’ defined in both module C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGUNIT2.OBJ and C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGUNIT1.OBJ

что это такое?
Как сделать чтобы программа работала?

:rolleyes:Re: Unresolved external — Ошибка при компиляции
Unresolved external — это сообщение линкера, означает, что в исходниках используется функция, которой нет в подключенных библиотеках и он не знает, что прилинковывать.

C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT =L TT+¦+=L+ -¦+++гDEBUGUNIT2.OBJ

Это означает только одно: пути к проектам Билдера НЕ МОГУТ содержать русские символы!

Re[2]: Unresolved external — Ошибка при компиляции
Спасибо — ответ понятный, написан вполне человеческим языком — а то сколько форумы не рыл — там была одна тока бредятина малопонятная
——————————————————————————————————————————————————————-
пути к проектам Билдера НЕ МОГУТ содержать русские символы!

— вот почти та же программа — все символы в пути латинские:
——————————————————————————————————-
[ILINK32 Error] Error: Unresolved external ‘_A’ referenced from C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT ON ADDING FRACTIONSDEBUGUNIT1.OBJ
[ILINK32 Error] Error: Unresolved external ‘_B’ referenced from C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT ON ADDING FRACTIONSDEBUGUNIT1.OBJ
[ILINK32 Error] Error: Unresolved external ‘_Reply’ referenced from C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT ON ADDING FRACTIONSDEBUGUNIT1.OBJ
[ILINK32 Error] Error: Unresolved external ‘_User’ referenced from C:DOCUMENTS AND SETTINGSGAMESRAD STUDIOPROJECTSTECT ON ADDING FRACTIONSDEBUGUNIT1.OBJ
——————————————
или я не там смотрю?
— где посмотреть пути к проектам?
———————————————————-

в исходниках используется функция, которой нет в подключенных библиотеках
— насколько понял эти библиотеки подключаются к проекту из главного окошка Билдера (Shift + F11), где то на форумах прочитал что к проекту надо подключить «Wininet.lib» (из каталога C:Program FilesCodeGearRAD Studio5.0libpsdk) — подключил — запустил компиляцию программы — не помогло — ошибки осталась те же.
————————————————-
Ошибки линкера стали выскакивать после того как подключил Хидер (Хедер), вот собственно он:
————————————————————————————
// extern int Examples[5][2];
// extern int Estimation;
//extern int Answers[5][2];
//extern int User[];

//extern const int n = 2; // для массива Answers[][n] //

extern double Reply[15]; // задание одномерного массива правилынх ответов
extern double User[15]; // ответы пользователя //

extern double A[15]; // Масивы для заполнения поля Tmemo
extern double B[15];

// переменные для формы регистрации //

extern AnsiString Names ; // задание новой строки //
extern AnsiString Class ;
extern AnsiString Surname ;
—————————————————————————-

может в нём что напутано неправильно написано?
хотя в других программах всё работает вполне нормально — когда так же точно Хидер оформляю

:rolleyes:Re[3]: Unresolved external — Ошибка при компиляции
extern double Reply[15]; // задание одномерного массива правилынх ответов
extern double User[15]; // ответы пользователя //

extern double A[15]; // Масивы для заполнения поля Tmemo
extern double B[15];
————————
Слово «extern» в си означает, что переменная описана где-то в другом модуле, а в текущем описывается просто ссылка, чтобы ей можно было пользоваться. Вот реального описания этих переменных похоже нигде нет. Или уберите «extern» из их описания здесь или опишите их реально в другом модуле.

//——————————————————————//
Re[4]: Unresolved external — Ошибка при компиляции
Спасибо большое — а то как обезьяна пишу чего то и не совсем понимаю что это — поправил хидер Всё работает

Спасибо

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Main.h"
#include "SendMessage.h"
#include "ShowMessage.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "trayicon"
#pragma resource "*.dfm"
TMainForm *MainForm;
static AnsiString ComputerName;
static AnsiString Address;
static TListItem *LI;
static TStringList *UserList;
static AnsiString ADirectory;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::UDPServerUDPRead(TObject *Sender,TStream *AData, TIdSocketHandle *ABinding) {
     int Show;
     AnsiString Tmp,RemoteName,Message;
     TStringStream* SS=new TStringStream("");
     SS->CopyFrom(AData,AData->Size);
     Tmp=SS->DataString;
     RemoteName=Tmp.SubString(Tmp.Pos("(")+1,Tmp.Pos(")")-Tmp.Pos("(")-1);
     Show=1;
     if (Tmp.Pos("###Start###")!=0) {
        if (Tmp.Pos(ComputerName)==0) {
           if (MainForm->Active==True) {
              UDPServer->Send(ABinding->PeerIP,4000,"###Here And Active###("+ComputerName+")");
           } else {
              UDPServer->Send(ABinding->PeerIP,4000,"###Here And Inactive###("+ComputerName+")");
           }
           ChatInputOutput->Lines->Add("Подключился: "+RemoteName);
           UserList->Add(RemoteName);
           LI=UsersListView->Items->Add();
           LI->Caption=RemoteName;
           LI->ImageIndex=-1;
           LI->Indent=-1;
           LI->SubItems->Add("");
           LI->SubItemImages[0]=0;
           LI->SubItems->Add(""Неактивен"");
           MediaPlayer->FileName=ADirectory+"Start.wav";
           MediaPlayer->Open();
           MediaPlayer->Play();
        }
        Show=0;
     }
     if (Tmp.Pos("###Here And Active###")!=0) {
        if (Tmp.Pos(ComputerName)==0) {
           ChatInputOutput->Lines->Add("Уже в сети: "+RemoteName);
           UserList->Add(RemoteName);
           LI=UsersListView->Items->Add();
           LI->Caption=RemoteName;
           LI->ImageIndex=-1;
           LI->Indent=-1;
           LI->SubItems->Add("");
           LI->SubItemImages[0]=0;
           LI->SubItems->Add(""Активен"");
        }
        Show=0;
     }
     if (Tmp.Pos("###Here And Inactive###")!=0) {
        if (Tmp.Pos(ComputerName)==0) {
           ChatInputOutput->Lines->Add("Уже в сети: "+RemoteName);
           UserList->Add(RemoteName);
           LI=UsersListView->Items->Add();
           LI->Caption=RemoteName;
           LI->ImageIndex=-1;
           LI->Indent=-1;
           LI->SubItems->Add("");
           LI->SubItemImages[0]=0;
           LI->SubItems->Add(""Неактивен"");
        }
        Show=0;
     }
     if (Tmp.Pos("###Stop###")!=0) {
        if (Tmp.Pos(ComputerName)==0) {
           ChatInputOutput->Lines->Add("Отключился: "+RemoteName);
           if (UserList->IndexOf(RemoteName)!=-1) {
              UsersListView->Items->Delete(UserList->IndexOf(RemoteName));
              UserList->Delete(UserList->IndexOf(RemoteName));
           }
        }
        Show=0;
     }
     if (Tmp.Pos("###Active###")!=0) {
        if (Tmp.Pos(ComputerName)==0) {
           if (UserList->IndexOf(RemoteName)!=-1) {
              LI=UsersListView->Items->Item[UserList->IndexOf(RemoteName)];
              LI->SubItems->Strings[1]=""Активен"";
           }
        }
        Show=0;
     }
     if (Tmp.Pos("###Inactive###")!=0) {
        if (Tmp.Pos(ComputerName)==0) {
           if (UserList->IndexOf(RemoteName)!=-1) {
              LI=UsersListView->Items->Item[UserList->IndexOf(RemoteName)];
              LI->SubItems->Strings[1]=""Неактивен"";
           }
        }
        Show=0;
     }
     if (Tmp.Pos("###Activate###")!=0) {
        TrayIcon->Restore();
        MediaPlayer->FileName=ADirectory+"Call.wav";
        MediaPlayer->Open();
        MediaPlayer->Play();
        Show=0;
     }
     if (Tmp.Pos("###ChatMessage###")!=0) {
        Message=Tmp.SubString(Tmp.Pos(")")+2,Tmp.Length()-Tmp.Pos(")")-1);
     }
     if (Tmp.Pos("###PrivateMessage###")!=0) {
        Message=Tmp.SubString(Tmp.Pos(")")+2,Tmp.Length()-Tmp.Pos(")")-1);
        SS->Position=0;
        SS->WriteString(Message);
        SS->Position=0;
        ShowMessageForm->MessageOutput->Lines->LoadFromStream(SS);
        TrayIcon->Restore();
        MediaPlayer->FileName=ADirectory+"Message.wav";
        MediaPlayer->Open();
        MediaPlayer->Play();
        ShowMessageForm->ShowModal();
        Show=0;
     }
     if (Show==1) {
        ChatInputOutput->Lines->Add(RemoteName+": "+Message);
     }
     if (UsersListView->Items->Count>0) {
        TrayIcon->IconIndex=0;
     } else {
        TrayIcon->IconIndex=1;
     }
     delete SS;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::SendBtnClick(TObject *Sender) {
     UDPServer->Broadcast("###ChatMessage###("+ComputerName+") "+MessageInput->Text,4000);
     MessageInput->Text="";
     MessageInput->SetFocus();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) {
     UDPServer->Broadcast("###Stop###("+ComputerName+")",4000);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ApplicationEventsException(TObject *Sender, Exception *E) {
     Application->MessageBox("","",MB_OK);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ApplicationEventsActivate(TObject *Sender) {
     UDPServer->Broadcast("###Active###("+ComputerName+")",4000);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ApplicationEventsDeactivate(TObject *Sender) {
     UDPServer->Broadcast("###Inactive###("+ComputerName+")",4000);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ChatInputOutputEnter(TObject *Sender) {
     MessageInput->SetFocus();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::UsersListViewEnter(TObject *Sender) {
     MessageInput->SetFocus();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::UsersListViewContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled) {
     if (UsersListView->ItemIndex!=-1) {
        PopupMenu->Popup(MainForm->Left+UsersListView->Left+MousePos.x,MainForm->Top+UsersListView->Top+MousePos.y+50);
     }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ApplicationEventsMinimize(TObject *Sender) {
     TrayIcon->Minimize();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::CallMenuItemClick(TObject *Sender) {
     UDPServer->Send(UsersListView->Selected->Caption,4000,"###Activate###("+ComputerName+")");
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::SendMenuItemClick(TObject *Sender) {
     int i,Result;
     TStringStream *Message=new TStringStream("");
     SendMessageForm->UserSelect->Clear();
     SendMessageForm->UserSelect->Items->Add("<Всем пользователям>");
     for (i=1;i<=UserList->Count;i++) {
         SendMessageForm->UserSelect->Items->Add(UserList->Strings[i-1]);
     }
     SendMessageForm->UserSelect->ItemIndex=UsersListView->ItemIndex+1;
     Result=SendMessageForm->ShowModal();
     if (Result==1) {
         SendMessageForm->MessageInput->Lines->SaveToStream(Message);
         Message->Position=0;
         if (SendMessageForm->UserSelect->ItemIndex==0) {
            UDPServer->Broadcast("###PrivateMessage###("+ComputerName+") "+Message->DataString,4000);
         } else {
            UDPServer->Send(UserList->Strings[SendMessageForm->UserSelect->ItemIndex-1],4000,"###PrivateMessage###("+ComputerName+") "+Message->DataString);
         }
     }
     delete Message;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender) {
     UserList=new TStringList();
     ComputerName="qwerty";
     UDPServer->Broadcast("###Start###("+ComputerName+")",4000);
     ADirectory=Application->ExeName.SubString(1,Application->ExeName.LastDelimiter("\"));
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormDestroy(TObject *Sender) {
     delete UserList;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::TrayIconRestore(TObject *Sender) {
     MainForm->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ExitMenuItemClick(TObject *Sender) {
     UDPServer->Broadcast("###Stop###("+ComputerName+")",4000);
     Application->Terminate();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::SendAllMenuItemClick(TObject *Sender) {
     int i,Result;
     TStringStream *Message=new TStringStream("");
     SendMessageForm->UserSelect->Clear();
     SendMessageForm->UserSelect->Items->Add("<Всем пользователям>");
     for (i=1;i<=UserList->Count;i++) {
         SendMessageForm->UserSelect->Items->Add(UserList->Strings[i-1]);
     }
     SendMessageForm->UserSelect->ItemIndex=0;
     Result=SendMessageForm->ShowModal();
     if (Result==1) {
         SendMessageForm->MessageInput->Lines->SaveToStream(Message);
         Message->Position=0;
         if (SendMessageForm->UserSelect->ItemIndex==0) {
            UDPServer->Broadcast("###PrivateMessage###("+ComputerName+") "+Message->DataString,4000);
         } else {
            UDPServer->Send(UserList->Strings[SendMessageForm->UserSelect->ItemIndex-1],4000,"###PrivateMessage###("+ComputerName+") "+Message->DataString);
         }
     }
     delete Message;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::MediaPlayerNotify(TObject *Sender) {
     MediaPlayer->Close();
}
//---------------------------------------------------------------------------

June 8 2011, 16:45

Category:

  • Игры
  • Cancel

Разнопрограммизм — деятельность очень увлекательная. Стопиццот разнообразных квестов поджидают в самые неожиданные моменты.
Понадобилась мелкая программка, сохранять-добавлять кусты реестра и немножко файлов копировать. По результатам подсказки «помощь зала» было принято решение собрать в C++ Builder6. Билдера этого я ранее в глаза не видела, как и С++. Беззастенчиво юзая «помощь зала» и интернеты, я таки начала это собирать.
Была собрана и отлажена прога: формочка о пяти кнопочках, свистелками назначила на кнопочках пиктограммы и всплывающие хинты. Теперь это надо запускать на компах без билдера. Ага, здесь смайлики ))))

Чтобы собранное в билдере работало на компах без билдера надо сделать так:

Убери галочки:
Project->Options->Linker: "Use dynamic RTL"
Project->Options->Packages: "Build with runtime packages"

После снятия этих галок твою прогу можно будет запускать на любом компе

И после снятия этих галочек проект перестал собираться и стал казать такое:

[Linker Error] Unresolved external '__fastcall Filectrl::SelectDirectory(const System::AnsiString, const System::WideString, System::AnsiString&)' referenced from D:SANA_DOSC++REGEXPORTUNIT1.OBJ

Cпросила у гугла про этот линкед еррор. Гугл знал ответ.

Полечилось так:

в билдере сделать Project|Add to project...
и добавить либу...CBuilder6LibReleasevclx.lib

Заработало. Квест пройден. Еще одна запись под тегом «шпаргалки».

PS. И нифига нет страшного в с++. Язык как язык. Интерфейс не гламурный у билдера, ну и фиг с ним. Квест с линкером нифига не порадовал, это да… С любой средой и в любом языке есть моменты, когда разговариваешь матом. Непонятно, отчего с++ считается мегакруто и дико сложно…

 

 Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 21:27 


24/01/22
61

main.cpp

#pragma hdrstop
#pragma argsused

#ifdef _WIN32
#include <tchar.h>
#else
  typedef char _TCHAR;
  #define _tmain main
#endif

#include <stdio.h>
#include <iostream>
#include <conio.h>
#include «List.h»
int _tmain(int argc, _TCHAR* argv[])
{
        List<int> c;

        getch();
        return 0;
}

List.h

//—————————————————————————

#ifndef ListH
#define ListH

#include<iostream>
template<typename T>
class List
{
        private:
    class _Node
        {
        public:
                _Node* m_next; //Указатель на следующий эл-т
                _Node* m_prev; //Указатель на предыдущий эл-т
                T m_data; //Значение эл-та

                _Node(T data = T{}, _Node* prev = nullptr, _Node* next = nullptr)
                        :m_data{ data }, m_prev{ prev }, m_next{ next }
                {
                }
        };

        _Node* m_first; //Указатель на первый эл-т списка
        _Node* m_last; //Указатель на последний эл-т списка
        int m_size;

    public:

        class Iterator
        {
        private:
                _Node* m_current;

        public:
                Iterator(_Node* first) : m_current{ first }
                {
                }

                T& operator++();
                T operator++(int);

                T& operator();
                T operator(int);

                bool  operator==(const Iterator& it);
                bool  operator!=(const Iterator& it);
                T& operator*();

        };

        List();
        ~List();

        friend std::ostream& operator<< (std::ostream& out, const List<T>& list);

        friend std::istream& operator>> (std::istream& in, List<T>& list);

        //Поместить эл-т в конец списка
        void pushBack(T el);
        //Убрать эл-т из конца списка
        void popBack();

        //Добавить эл-т в начало списка
        void pushFront(T el);
        //Удалить эл-т из начала списка
        void popFront();

        Iterator begin() const{ return m_first; }
        Iterator end() const{ return nullptr; }

        //Удаление i эл-та
        void remove(Iterator& i);
};
#endif

List.cpp

//—————————————————————————

#pragma hdrstop

#include «List.h»
template<typename T>
List<T>::List()
        : m_size{ 0 }, m_first{ nullptr }, m_last{ nullptr }
{

}

template <typename T>
List<T>::~List()
{
        //Удаление эл-тов, пока список не станет пустым
        _Node* k{ };
        for (_Node* i = m_first; i != nullptr;)
        {
                k = i;
                i = i>m_next;
                delete k;
        }
}

#pragma package(smart_init)

Подскажите, что не так? Пишет: «[ilink32 Error] Error: Unresolved external ‘List<int>::List<int>()’ referenced from C:USERS…», «Error: Unable to perform link»

Профиль  

zykov 

 Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 21:49 


18/09/21
1533

В конце «List.cpp» добавить

template class List<int>;

Или перенести конструктор и деструктор из «List.cpp» в «List.h».

Профиль  

XeuTeP_KoLLIu 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 22:08 


24/01/22
61

В конце «List.cpp» добавить

template class List<int>;

Или перенести конструктор и деструктор из «List.cpp» в «List.h».

Спасибо, это помогло. Но почему так странно?

Профиль  

zykov 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 22:21 


18/09/21
1533

Ничего странного.
Это же шаблон (template).
Пока не создан instance, то для его функций нет кода.

Первый вариант явно создаёт instance для типа int прямо в List.cpp, с которым потом можно слинковаться.

Второй вариант — пернос всего в заголовок — делает доступным полное описание методов во всех исходниках, где включен этот заголовок. Там и линковаться не надо. Код будет сгенерирован при использовании обекта типа int (или какого другого).

Профиль  

XeuTeP_KoLLIu 

 Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 22:24 


24/01/22
61

Ничего странного.
Это же шаблон (template).
Пока не создан instance, то для его функций нет кода.

Первый вариант явно создаёт instance для типа int прямо в List.cpp, с которым потом можно слинковаться.

Второй вариант — пернос всего в заголовок — делает доступным полное описание методов во всех исходниках, где включен этот заголовок. Там и линковаться не надо. Код будет сгенерирован при использовании обекта типа int (или какого другого).

До этого я писал в visual studio, и ничего такого не требовалось.

— 09.02.2023, 22:27 —

Погодите, разве это не костыль? Смысл же шаблона в том, что я не знаю какой будет использоваться тип данных, а тут я явно указываю, что это — int.

— 09.02.2023, 22:32 —

Я дописал operator >> и operator <<. Выдается та же самая ошибка
[ilink32 Error] Error: Unresolved external ‘operator >>(std::basic_istream<char, std::char_traits<char> >&, List<int>&)’ referenced from C:USERS
Перенес все из List.cpp в List.h. Не помогло. В visual studio все работает нормально.

Профиль  

zykov 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 22:32 


18/09/21
1533

Нет, это фича языка.
Хотите для любого типа — пишите всё в заголовке. Плата за это, каждый раз это должно заново компилироваться.
Хотите скомпилировать один раз и потом линковать, делайте Explicit instantiation.
Никто не мешает сделать для нескольких типов вроде:

template class List<int>;
template class List<double>;
template class List<float>;

Профиль  

XeuTeP_KoLLIu 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 22:34 


24/01/22
61

А если пользователь захочет создать список со своим типом данных?

Профиль  

zykov 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение09.02.2023, 22:37 


18/09/21
1533

Точно так же можно сделать:

template class List<TMyType>;

Только нужно туда заголовок подключить с этим своим типом.

Профиль  

TheRuinedMap 

 Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение10.02.2023, 18:37 

Аватара пользователя


28/10/21
82

До этого я писал в visual studio, и ничего такого не требовалось.

Вы что-то выдумываете. Это требуется всегда и везде по совершенно очевидным и естественным причинам: шаблон — это фактически усовершенствованный «макрос».

Погодите, разве это не костыль? Смысл же шаблона в том, что я не знаю какой будет использоваться тип данных, а тут я явно указываю, что это — int.

Совершенно верно. В таком применении это — костыль и делать так не нужно.

Эта фича языка (явное инстанцирование) предназначена совсем для других целей: для ускорения компиляции шаблона для какого-то фиксированного (и часто используемого) набора заранее известных аргументов. Явное инстанцирование не предназначено для решения вашей исходной проблемы.

Все определения шаблона должно быть видны везде, где они используются. То есть определения шаблонов нельзя делить на .h и .cpp файлы. Все целиком должно располагаться в .h файле.

Я дописал operator >> и operator <<. Выдается та же самая ошибка

Я не вижу этого в приведенном на данный момент коде, но мой дар ясновидения подсказывает мне, что это уже совсем другая ошибка. Вы на самом деле определили не тот оператор, который объявили, потому и получаете ошибки линковки. Это очень распространённая ошибка при определении «друзей» для шаблонных классов.

Простейший вариант решения этой проблемы: поместите определения этих операторов прямо в класс, прямо туда где вы их объявили. Более того (не вдаваясь в детали): для того варианта объявления friend-функции шаблона класса, который вы использовали в вашем коде, в С++ невозможно предоставить определение за пределами определения шаблона класса — для этого в С++ просто не существует синтаксиса

.

Профиль  

XeuTeP_KoLLIu 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение10.02.2023, 20:25 


24/01/22
61

До этого я писал в visual studio, и ничего такого не требовалось.

Вы что-то выдумываете. Это требуется всегда и везде по совершенно очевидным и естественным причинам: шаблон — это фактически усовершенствованный «макрос».

Погодите, разве это не костыль? Смысл же шаблона в том, что я не знаю какой будет использоваться тип данных, а тут я явно указываю, что это — int.

Совершенно верно. В таком применении это — костыль и делать так не нужно.

Эта фича языка (явное инстанцирование) предназначена совсем для других целей: для ускорения компиляции шаблона для какого-то фиксированного (и часто используемого) набора заранее известных аргументов. Явное инстанцирование не предназначено для решения вашей исходной проблемы.

Все определения шаблона должно быть видны везде, где они используются. То есть определения шаблонов нельзя делить на .h и .cpp файлы. Все целиком должно располагаться в .h файле.

Я дописал operator >> и operator <<. Выдается та же самая ошибка

Я не вижу этого в приведенном на данный момент коде, но мой дар ясновидения подсказывает мне, что это уже совсем другая ошибка. Вы на самом деле определили не тот оператор, который объявили, потому и получаете ошибки линковки. Это очень распространённая ошибка при определении «друзей» для шаблонных классов.

Простейший вариант решения этой проблемы: поместите определения этих операторов прямо в класс, прямо туда где вы их объявили. Более того (не вдаваясь в детали): для того варианта объявления friend-функции шаблона класса, который вы использовали в вашем коде, в С++ невозможно предоставить определение за пределами определения шаблона класса — для этого в С++ просто не существует синтаксиса

.

Спасибо. Это помогло. Только я все равно не понимаю почему все работает именно так.

Профиль  

worm2 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение10.02.2023, 20:36 

Заслуженный участник
Аватара пользователя


01/08/06
2961
Уфа

Я почти не знаю C++. Но, помнится, краем уха где-то слышал байку, что есть компиляторы, умеющие специализировать шаблон в рантайме. Якобы в библиотеку рантайма специально для этого внедрялся какой-то урезанный компилятор.
Хотя, возможно, я что-то напутал. Возможно, это было про другой язык.

Профиль  

zykov 

 Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение10.02.2023, 20:51 


18/09/21
1533

worm2

Есть такая штука — JIT (just-in-time) компиляция.
Видел как-то на Java такое исследовали (не знаю, есть ли где-то в production).
Но там обычно речь про оптимизацию с учётом реальной статисики исполнения кода (для текущего профиля данных).

Профиль  

TheRuinedMap 

 Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение10.02.2023, 20:55 

Аватара пользователя


28/10/21
82

Только я все равно не понимаю почему все работает именно так.

О чем именно речь? О шаблонах в целом? Или о тонкостях определения дружественных функций для шаблонных классов?

— 10.02.2023, 10:00 —

Но, помнится, краем уха где-то слышал байку, что есть компиляторы, умеющие специализировать шаблон в рантайме.

Это что-то невероятное.

Были компиляторы, которые реализовывали другой подход к инстанцированию шаблонов во время компиляции. Вместо того, чтобы плодить множественные копии одного и того же кода, а потом вычищать лишние копии на стадии линковки (как поступают все современные реализации), они использовали двухпроходный подход: первым проходом они собирали информацию о том, какие специализации шаблонов используются в программе, а вторым проходом генерировали один-единственный раз только эти требуемые инстанциации. Так работал родной компилятор С++ для Sun Solaris.

Но в конечном итоге такой подход не выжил.

Профиль  

warlock66613 

 Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение11.02.2023, 11:20 

Заслуженный участник


02/08/11
6527

я все равно не понимаю почему все работает именно так

Если речь про исходную проблему — всё работает именно так, потому что каждый .cpp файл компилируется независимо и не «видит» кода в других .cpp файлах.

(картинка)

Изображение

Профиль  

XeuTeP_KoLLIu 

Re: Ошибка Unresolved external. c++ builder 10.4

Сообщение11.02.2023, 23:52 


24/01/22
61

Только я все равно не понимаю почему все работает именно так.

О чем именно речь? О шаблонах в целом? Или о тонкостях определения дружественных функций для шаблонных классов?

— 10.02.2023, 10:00 —

Но, помнится, краем уха где-то слышал байку, что есть компиляторы, умеющие специализировать шаблон в рантайме.

Это что-то невероятное.

Были компиляторы, которые реализовывали другой подход к инстанцированию шаблонов во время компиляции. Вместо того, чтобы плодить множественные копии одного и того же кода, а потом вычищать лишние копии на стадии линковки (как поступают все современные реализации), они использовали двухпроходный подход: первым проходом они собирали информацию о том, какие специализации шаблонов используются в программе, а вторым проходом генерировали один-единственный раз только эти требуемые инстанциации. Так работал родной компилятор С++ для Sun Solaris.

Но в конечном итоге такой подход не выжил.

Дружественные функции.

Профиль  

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы

Понравилась статья? Поделить с друзьями:
  • Ошибка unknown error fff red dead redemption 2
  • Ошибка unrecoverable fault please restart the game
  • Ошибка unknown device работает неверно код 43
  • Ошибка unreal engine is exiting due to d3d
  • Ошибка unityplayer dll как исправить ошибку