Определение
Данная ошибка означает, что в процессе компоновки программы, компоновщик не смог найти определение некоторой сущности, на которую есть ссылка (попытка использования) в программе.
К таким сущностям может относиться, например, функция или переменная.
Причины и решения
Возможных причин появления ошибки может быть несколько и это зависит от того, что представляет из себя собираемый проект. Всё множество ситуаций можно разбить на две большие группы:
Используются сторонние библиотеки
-
Не указана необходимая (статическая) библиотека для компоновщика.
Например, к проекту подключен только
*.h
файл с объявлениями, но отсутствует код реализации, обычно это*.lib
или*.a
файлы (в зависимости от используемой системы).
Требуется явно подключить библиотеку к проекту.
-
Для Visual C++ это можно сделать добавлением следующей строки прямо в код:
#pragma comment(lib, "libname.lib")
-
Для
gcc/clang
требуется указать файл через ключ-l
(эль) -
Для Qt в .pro файле нужно использовать переменную
LIBS
:LIBS += -L[путь_к_библиотеке] -l[имя_библиотеки]
-
Для системы сборки
cmake
естьtarget_link_libraries
.
-
Библиотека указана, но необходимая сущность, например, класс или функция фактически не экспортируется из библиотеки. Под Windows это может возникать из-за отсуствия
__declspec(dllexport)
перед сущностью. Обычно это решается макросами. Данная ситуация чаще всего характерна именно для библиотек, находящихся в процессе разработки, и доступных для модификации самому разработчику, нежели для каких-то стабильных версий действительно внешних для проекта библиотек. После разрешения экспортирования библиотеку, конечно же, нужно пересобрать перед непосредственным использованием проблемной сущности. -
Библиотека указана, но не совпадает разрядность библиотеки и компилируемого кода.
В общем случае, разрядность собираемого проекта (приложения или библиотеки) должна совпадать с разрядностью используемой сторонней библиотеки. Обычно производители библиотек предоставляют возможность выбора 32 или 64 бит версию использовать. Если библиотека поставляется в исходных кодах и собирается отдельно от текущего проекта, нужно также выбрать правильную разрядность.
-
Библиотека указана, но она собрана для другой (не совместимой) ОС.
Например при сборке проекта в Windows осуществляется попытка использовать бинарный файл, собранный для Linux. В данном случае нужно использовать файлы, подходящие для вашей ОС.
-
Библиотека указана, но она собрана другим компилятором, не совместимым с используемым.
Объектные файлы, полученные путем сборки C++ кода разными компиляторами для одной и той же ОС могут быть бинарно несовместимы друг с другом. Требуется использовать совместимые (скорее всего и вовсе одинаковые) компиляторы.
-
Библиотека указана, и собрана тем же компилятором, что и основной проект, но используются разные версии Run-Time библиотек.
Например, для Visual C++ возможна ситуация, когда библиотека собрана с ключом
/MDd
, а основной проект с/MTd
. Требуется задать ключи так, чтобы использовались одинаковые версии Run-Time библиотек.
Сторонние библиотеки не используются
-
Просто отсутствует определение функции.
void f(int); // всего лишь объявление. Нет `тела` функции int main(){ f(42); // undefined reference to `f(int)' }
Требуется добавить определение функции
f
:void f(int) { // тело функции }
Может быть ещё частный случай с ошибкой вида:
undefined reference to `vtable for <имя_класса>`
Такая ошибка возникает, если объявленная виртуальная функция класса, не являющаяся чистой (
=0
), не содержит реализации.class C { virtual void f(int); };
Нужно такую реализацию добавить. Если это делается вне класса, надо не забыть указать имя проблемного класса, иначе это будет просто свободная функция, которая не устраняет указанную проблему:
void C::f(int) { // виртуальная функция-член вне определения класса // тело функции } void f(int) { // свободная функция, не устраняющая проблему // тело функции }
Аналогичная ситуация может возникать при использовании пространств имён, когда объявлении функции находится в пространстве имён:
// В заголовочном файле namespace N { void f(int); };
а при реализации указать это пространство имён забыли:
// В файле реализации void f(int) { // функция в глобальном пространстве имён, не устраняющая проблему // тело функции } namespace N { void f(int) { // функция в нужном пространстве имён // тело функции } } // конец пространства имён
Стоит заметить, что C++ разрешает перегрузку функций (существование одноимённых функций, но с разным набором параметров), и в этом случае важно, чтобы сигнатуры функций при объявлении и определении совпадали. Например, вместо объявленной
void f(int)
была реализована другая:void f(const char*) { // const char* вместо int // тело функции }
При вызове
f(42)
будет ошибка:undefined reference to `f(int)'
Наличие связки шаблонного класса и дружественной функции также может приводить к ошибке. Например:
template <class T> struct C { friend void f(C<T>); // объявляет *НЕ*шаблонную дружественную функцию }; template <class T> // определяет шаблонную функцию void f(C<T>) { } int main() { C<int> c; f(c); // undefined reference to `f(C<int>)' }
Чтобы объявить шаблонную дружественную функцию, требуется добавить указание шаблонности:
template <class T> struct C { template <class V> // добавили шаблонность для friend функции friend void f(C<T>); };
Важно, что имя шаблонного параметра для дружественной функции должно отличаться от имени параметра шаблонного класса
T
, т.к. иначе будет ошибка о сокрытии имени. В частном случае имя класса можно вовсе не указывать, и оставитьtemplate <class>
. Но это не всегда будет правильным решением, т.к. фактически могла потребоваться дружественная специализация шаблона функции, а не сама шаблонная функция. Подробнее об использовании дружественных функций в шаблонном классе можно ознакомиться здесь. -
Отсутствует определение статической переменной класса.
struct S { static int i; }; int main() { S s; s.i = 42; // undefined reference to `S::i' }
Нужно добавить определение (выделить память) переменной:
int S::i;
-
Неправильная реализация шаблонного кода.
Например, реализация шаблонного кода помещена в
*.cpp
файл, хотя она должна находиться полностью в подключаемом*.h
файле. Это требуется по той причине, что компилятор обрабатывает каждый модуль независимо, и в момент инстанцирования шаблона (подстановки конкретного типа) код его реализации должен быть виден. При этом если возможные типы шаблона известны заранее, можно произвести инстанцирование сразу рядом с телом шаблона и не предоставлять его наружу в исходном коде заголовочного файла. Пример:// unit.h #pragma once template <class T> T f(T); // объявление шаблона без реализации
// unit.cpp #include "unit.h" template <class T> T f(T t) { return t + t; } // реализация шаблона template int f<int>(int); // явное инстанцирование для int template double f<double>(double); // явное инстанцирование для double
// main.cpp #include "unit.h" int main() { f(2); // ok int f(1.5); // ok double f('a'); // undefined reference to `char f<char>(char)' }
-
Файл с кодом не был скомпилирован.
Например, в случае использования make-файла не было прописано правило построения файла, а в случае использования IDE типа Visual Studio
*.cpp
файл не добавлен в список файлов проекта. -
Виртуальная функция в базовом классе не объявлена как
= 0
(pure-virtual).struct B { void virtual f(); }; struct D : B { void f() {} }; int main() { D d; }
При использовании иерархии классов функция в базовом классе, не имеющая реализации должна быть помечена как «чистая»:
struct B { void virtual f() = 0; };
-
Имя не имеет внешнего связывания.
Например, есть объявление функции
f
в модулеА
и даже ее реализация в модулеB
, но реализация помечена какstatic
:// A.cpp void f(); int main() { f(); // undefined reference to `f()' } // B.cpp static void f() {}
Аналогичная ситуация может возникнуть при использовании безымянного пространства имен:
// B.cpp namespace { void f() {} }
Или даже при наличии
inline
у функции:// B.cpp inline void f() {}
Aqua77 25 / 25 / 19 Регистрация: 13.07.2015 Сообщений: 433 |
||||
1 |
||||
16.05.2016, 04:02. Показов 3178. Ответов 4 Метки нет (Все метки)
Завершённую программу не могу скомпилировать в Release чтобы другие пк могли ей пользоваться, выдаётся ошибка: ссылка на неразрешенный внешний символ _main в функции «int __cdecl __scrt_common_main_seh(void)» (?__scrt_common_main_seh@@YAHXZ) Код если поможет решить проблему
__________________
0 |
Модератор 12639 / 10133 / 6102 Регистрация: 18.12.2011 Сообщений: 27,169 |
|
16.05.2016, 07:03 |
2 |
Сообщение говорит о том, что точка входа должна быть _main
0 |
Aqua77 25 / 25 / 19 Регистрация: 13.07.2015 Сообщений: 433 |
||||
16.05.2016, 14:03 [ТС] |
3 |
|||
Поменял на
Всё ровно та же ошибка, и в Debug ошибку стал выдавать
0 |
zss Модератор 12639 / 10133 / 6102 Регистрация: 18.12.2011 Сообщений: 27,169 |
||||||||
16.05.2016, 14:37 |
4 |
|||||||
Разберитесь с типом проекта.
или
0 |
Администратор 9356 / 4638 / 755 Регистрация: 17.04.2012 Сообщений: 9,490 Записей в блоге: 14 |
|
19.05.2016, 20:18 |
5 |
0 |
title | description | ms.date | f1_keywords | helpviewer_keywords | no-loc | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Linker Tools Error LNK2019 |
All about the Microsoft Visual Studio Linker error LNK2019 and how to diagnose and correct it in C and C++ code. |
09/07/2022 |
LNK2019 |
|
|
unresolved external symbol ‘symbol‘ referenced in function ‘function‘
The compiled code for function makes a reference or call to symbol, but the linker can’t find the symbol definition in any of the libraries or object files.
This error message is followed by fatal error LNK1120. To fix error LNK1120, you must fix all LNK2001 and LNK2019 errors first.
Possible causes
There are many ways to get this error. All of them involve a reference to a function or variable that the linker couldn’t resolve, or find a definition for. The compiler can identify when a symbol isn’t declared, but it can’t tell when the symbol isn’t defined. It’s because the definition may be in a different source file or library. If a symbol is referred to but never defined, the linker generates an unresolved external symbol error.
Here are some common problems that cause LNK2019:
The source file that contains the definition of the symbol isn’t compiled
In Visual Studio, make sure the source file that defines the symbol gets compiled as part of your project. Check the intermediate build output directory for a matching .obj file. If the source file isn’t compiled, right-click on the file in Solution Explorer, and then choose Properties to check the properties of the file. The Configuration Properties > General page should show an Item Type of C/C++ Compiler. On the command line, make sure the source file that contains the definition is compiled.
The object file or library that contains the definition of the symbol isn’t linked
In Visual Studio, make sure the object file or library that contains the symbol definition is linked as part of your project. On the command line, make sure the list of files to link includes the object file or library.
The declaration of the symbol isn’t spelled the same as the definition of the symbol
Verify you use the correct spelling and capitalization in both the declaration and the definition, and wherever the symbol is used or called.
A function is used but the type or number of the parameters don’t match the function definition
The function declaration must match the definition. Make sure the function call matches the declaration, and that the declaration matches the definition. Code that invokes function templates must also have matching function template declarations that include the same template parameters as the definition. For an example of a template declaration mismatch, see sample LNK2019e.cpp in the Examples section.
A function or variable is declared but not defined
LNK2019 can occur when a declaration exists in a header file, but no matching definition is implemented. For member functions or static data members, the implementation must include the class scope selector. For an example, see Missing Function Body or Variable.
The calling convention is different between the function declaration and the function definition
Some calling conventions (__cdecl
, __stdcall
, __fastcall
, and __vectorcall
) are encoded as part of the decorated name. Make sure the calling convention is the same.
A symbol is defined in a C file, but declared without using extern "C"
in a C++ file
A file that’s compiled as C creates decorated names for symbols that are different from the decorated names for the same symbols declared in a C++ file, unless you use an extern "C"
modifier. Make sure the declaration matches the compilation linkage for each symbol. Similarly, if you define a symbol in a C++ file that will be used by a C program, use extern "C"
in the definition.
A symbol is defined as static and then later referenced outside the file
In C++, unlike C, global constants have static
linkage. To get around this limitation, you can include the const
initializations in a header file and include that header in your .cpp files, or you can make the variable non-constant and use a constant reference to access it.
A static member of a class isn’t defined
A static class member must have a unique definition, or it will violate the one-definition rule. A static class member that can’t be defined inline must be defined in one source file by using its fully qualified name. If it isn’t defined at all, the linker generates LNK2019.
A build dependency is only defined as a project dependency in the solution
In earlier versions of Visual Studio, this level of dependency was sufficient. However, starting with Visual Studio 2010, Visual Studio requires a project-to-project reference. If your project doesn’t have a project-to-project reference, you may receive this linker error. Add a project-to-project reference to fix it.
An entry point isn’t defined
The application code must define an appropriate entry point: main
or wmain
for console applications, and WinMain
or wWinMain
for Windows applications. For more information, see main
function and command-line arguments or WinMain
function. To use a custom entry point, specify the /ENTRY
(Entry-Point Symbol) linker option.
You build a console application by using settings for a Windows application
If the error message is similar to unresolved external symbol WinMain referenced in function function_name, link by using /SUBSYSTEM:CONSOLE
instead of /SUBSYSTEM:WINDOWS
. For more information about this setting, and for instructions on how to set this property in Visual Studio, see /SUBSYSTEM
(Specify Subsystem).
You attempt to link 64-bit libraries to 32-bit code, or 32-bit libraries to 64-bit code
Libraries and object files linked to your code must be compiled for the same architecture as your code. Make sure the libraries your project references are compiled for the same architecture as your project. Make sure the /LIBPATH
or Additional Library Directories property points to libraries built for the correct architecture.
You use different compiler options for function inlining in different source files
Using inlined functions defined in .cpp files and mixing function inlining compiler options in different source files can cause LNK2019. For more information, see Function Inlining Problems.
You use automatic variables outside their scope
Automatic (function scope) variables can only be used in the scope of that function. These variables can’t be declared extern
and used in other source files. For an example, see Automatic (Function Scope) Variables.
You call intrinsic functions or pass argument types to intrinsic functions that aren’t supported on your target architecture
For example, if you use an AVX2 intrinsic, but don’t specify the /ARCH:AVX2
compiler option, the compiler assumes that the intrinsic is an external function. Instead of generating an inline instruction, the compiler generates a call to an external symbol with the same name as the intrinsic. When the linker tries to find the definition of this missing function, it generates LNK2019. Make sure you only use intrinsics and types supported by your target architecture.
You mix code that uses native wchar_t
with code that doesn’t
C++ language conformance work that was done in Visual Studio 2005 made wchar_t
a native type by default. If not all files have been compiled by using the same /Zc:wchar_t
settings, type references may not resolve to compatible types. Make sure wchar_t
types in all library and object files are compatible. Either update from a wchar_t
typedef, or use consistent /Zc:wchar_t settings when you compile.
You get errors for *printf*
and *scanf*
functions when you link a legacy static library
A static library that was built using a version of Visual Studio before Visual Studio 2015 may cause LNK2019 errors when linked with the UCRT. The UCRT header files <stdio.h>
, <conio.h>
, and <wchar.h>
now define many *printf*
and *scanf*
variations as inline
functions. The inlined functions are implemented by a smaller set of common functions. Individual exports for the inlined functions aren’t available in the standard UCRT libraries, which only export the common functions. There are a couple of ways to resolve this issue. The method we recommend is to rebuild the legacy library with your current version of Visual Studio. Make sure the library code uses the standard headers for the definitions of the *printf*
and *scanf*
functions that caused the errors. Another option for a legacy library that you can’t rebuild is to add legacy_stdio_definitions.lib
to the list of libraries you link. This library file provides symbols for the *printf*
and *scanf*
functions that are inlined in the UCRT headers. For more information, see the Libraries section in Overview of potential upgrade issues.
Third-party library issues and vcpkg
If you see this error when you’re trying to configure a third-party library as part of your build, consider using vcpkg. vcpkg is a C++ package manager that uses your existing Visual Studio tools to install and build the library. vcpkg supports a large and growing list of third-party libraries. It sets all the configuration properties and dependencies required for successful builds as part of your project.
Diagnosis tools
Sometimes it’s difficult to tell why the linker can’t find a particular symbol definition. Often the problem is that you haven’t included the code that contains the definition in your build. Or, build options have created different decorated names for external symbols. There are several tools and options that can help you diagnose LNK2019 errors.
-
The
/VERBOSE
linker option can help you determine which files the linker references. This option can help you verify whether the file that contains the definition of the symbol is included in your build. -
The
/EXPORTS
and/SYMBOLS
options of the DUMPBIN utility can help you discover which symbols are defined in your .dll and object or library files. Make sure the exported decorated names match the decorated names the linker searches for. -
The UNDNAME utility can show you the equivalent undecorated external symbol for a decorated name.
Examples
Here are several examples of code that causes LNK2019 errors, together with information about how to fix the errors.
A symbol is declared but not defined
In this example, an external variable is declared but not defined:
// LNK2019.cpp // Compile by using: cl /EHsc /W4 LNK2019.cpp // LNK2019 expected extern char B[100]; // B isn't available to the linker int main() { B[0] = ' '; // LNK2019 }
Here’s another example where a variable and function are declared as extern
but no definition is provided:
// LNK2019c.cpp // Compile by using: cl /EHsc LNK2019c.cpp // LNK2019 expected extern int i; extern void g(); void f() { i++; g(); } int main() {}
Unless i
and g
are defined in one of the files included in the build, the linker generates LNK2019. You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass .obj
files or .lib
files that contain the definitions to the linker.
A static data member is declared but not defined
LNK2019 can also occur when a static data member is declared but not defined. The following sample generates LNK2019, and shows how to fix it.
// LNK2019b.cpp // Compile by using: cl /EHsc LNK2019b.cpp // LNK2019 expected struct C { static int s; }; // Uncomment the following line to fix the error. // int C::s; int main() { C c; C::s = 1; }
Declaration parameters don’t match the definition
Code that invokes function templates must have matching function template declarations. Declarations must include the same template parameters as the definition. The following sample generates LNK2019 on a user-defined operator, and shows how to fix it.
// LNK2019e.cpp // compile by using: cl /EHsc LNK2019e.cpp // LNK2019 expected #include <iostream> using namespace std; template<class T> class Test { // The operator<< declaration doesn't match the definition below: friend ostream& operator<<(ostream&, Test&); // To fix, replace the line above with the following: // template<typename T> friend ostream& operator<<(ostream&, Test<T>&); }; template<typename T> ostream& operator<<(ostream& os, Test<T>& tt) { return os; } int main() { Test<int> t; cout << "Test: " << t << endl; // LNK2019 unresolved external }
Inconsistent wchar_t type definitions
This sample creates a DLL that has an export that uses WCHAR
, which resolves to wchar_t
.
// LNK2019g.cpp // compile with: cl /EHsc /LD LNK2019g.cpp #include "windows.h" // WCHAR resolves to wchar_t __declspec(dllexport) void func(WCHAR*) {}
The next sample uses the DLL in the previous sample, and generates LNK2019 because the types unsigned short*
and WCHAR*
aren’t the same.
// LNK2019h.cpp // compile by using: cl /EHsc LNK2019h LNK2019g.lib // LNK2019 expected __declspec(dllimport) void func(unsigned short*); int main() { func(0); }
To fix this error, change unsigned short
to wchar_t
or WCHAR
, or compile LNK2019g.cpp by using /Zc:wchar_t-
.
See also
For more information about possible causes and solutions for LNK2019, LNK2001, and LNK1120 errors, see the Stack Overflow question: What is an undefined reference/unresolved external symbol error and how do I fix it?
.
Your linkage consumes libraries before the object files that refer to them
- You are trying to compile and link your program with the GCC toolchain.
- Your linkage specifies all of the necessary libraries and library search paths
- If
libfoo
depends onlibbar
, then your linkage correctly putslibfoo
beforelibbar
. - Your linkage fails with
undefined reference to
something errors. - But all the undefined somethings are declared in the header files you have
#include
d and are in fact defined in the libraries that you are linking.
Examples are in C. They could equally well be C++
A minimal example involving a static library you built yourself
my_lib.c
#include "my_lib.h"
#include <stdio.h>
void hw(void)
{
puts("Hello World");
}
my_lib.h
#ifndef MY_LIB_H
#define MT_LIB_H
extern void hw(void);
#endif
eg1.c
#include <my_lib.h>
int main()
{
hw();
return 0;
}
You build your static library:
$ gcc -c -o my_lib.o my_lib.c
$ ar rcs libmy_lib.a my_lib.o
You compile your program:
$ gcc -I. -c -o eg1.o eg1.c
You try to link it with libmy_lib.a
and fail:
$ gcc -o eg1 -L. -lmy_lib eg1.o
eg1.o: In function `main':
eg1.c:(.text+0x5): undefined reference to `hw'
collect2: error: ld returned 1 exit status
The same result if you compile and link in one step, like:
$ gcc -o eg1 -I. -L. -lmy_lib eg1.c
/tmp/ccQk1tvs.o: In function `main':
eg1.c:(.text+0x5): undefined reference to `hw'
collect2: error: ld returned 1 exit status
A minimal example involving a shared system library, the compression library libz
eg2.c
#include <zlib.h>
#include <stdio.h>
int main()
{
printf("%sn",zlibVersion());
return 0;
}
Compile your program:
$ gcc -c -o eg2.o eg2.c
Try to link your program with libz
and fail:
$ gcc -o eg2 -lz eg2.o
eg2.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
collect2: error: ld returned 1 exit status
Same if you compile and link in one go:
$ gcc -o eg2 -I. -lz eg2.c
/tmp/ccxCiGn7.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
collect2: error: ld returned 1 exit status
And a variation on example 2 involving pkg-config
:
$ gcc -o eg2 $(pkg-config --libs zlib) eg2.o
eg2.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
What are you doing wrong?
In the sequence of object files and libraries you want to link to make your
program, you are placing the libraries before the object files that refer to
them. You need to place the libraries after the object files that refer
to them.
Link example 1 correctly:
$ gcc -o eg1 eg1.o -L. -lmy_lib
Success:
$ ./eg1
Hello World
Link example 2 correctly:
$ gcc -o eg2 eg2.o -lz
Success:
$ ./eg2
1.2.8
Link the example 2 pkg-config
variation correctly:
$ gcc -o eg2 eg2.o $(pkg-config --libs zlib)
$ ./eg2
1.2.8
The explanation
Reading is optional from here on.
By default, a linkage command generated by GCC, on your distro,
consumes the files in the linkage from left to right in
commandline sequence. When it finds that a file refers to something
and does not contain a definition for it, to will search for a definition
in files further to the right. If it eventually finds a definition, the
reference is resolved. If any references remain unresolved at the end,
the linkage fails: the linker does not search backwards.
First, example 1, with static library my_lib.a
A static library is an indexed archive of object files. When the linker
finds -lmy_lib
in the linkage sequence and figures out that this refers
to the static library ./libmy_lib.a
, it wants to know whether your program
needs any of the object files in libmy_lib.a
.
There is only object file in libmy_lib.a
, namely my_lib.o
, and there’s only one thing defined
in my_lib.o
, namely the function hw
.
The linker will decide that your program needs my_lib.o
if and only if it already knows that
your program refers to hw
, in one or more of the object files it has already
added to the program, and that none of the object files it has already added
contains a definition for hw
.
If that is true, then the linker will extract a copy of my_lib.o
from the library and
add it to your program. Then, your program contains a definition for hw
, so
its references to hw
are resolved.
When you try to link the program like:
$ gcc -o eg1 -L. -lmy_lib eg1.o
the linker has not added eg1.o
to the program when it sees
-lmy_lib
. Because at that point, it has not seen eg1.o
.
Your program does not yet make any references to hw
: it
does not yet make any references at all, because all the references it makes
are in eg1.o
.
So the linker does not add my_lib.o
to the program and has no further
use for libmy_lib.a
.
Next, it finds eg1.o
, and adds it to be program. An object file in the
linkage sequence is always added to the program. Now, the program makes
a reference to hw
, and does not contain a definition of hw
; but
there is nothing left in the linkage sequence that could provide the missing
definition. The reference to hw
ends up unresolved, and the linkage fails.
Second, example 2, with shared library libz
A shared library isn’t an archive of object files or anything like it. It’s
much more like a program that doesn’t have a main
function and
instead exposes multiple other symbols that it defines, so that other
programs can use them at runtime.
Many Linux distros today configure their GCC toolchain so that its language drivers (gcc
,g++
,gfortran
etc)
instruct the system linker (ld
) to link shared libraries on an as-needed basis.
You have got one of those distros.
This means that when the linker finds -lz
in the linkage sequence, and figures out that this refers
to the shared library (say) /usr/lib/x86_64-linux-gnu/libz.so
, it wants to know whether any references that it has added to your program that aren’t yet defined have definitions that are exported by libz
If that is true, then the linker will not copy any chunks out of libz
and
add them to your program; instead, it will just doctor the code of your program
so that:-
-
At runtime, the system program loader will load a copy of
libz
into the
same process as your program whenever it loads a copy of your program, to run it. -
At runtime, whenever your program refers to something that is defined in
libz
, that reference uses the definition exported by the copy oflibz
in
the same process.
Your program wants to refer to just one thing that has a definition exported by libz
,
namely the function zlibVersion
, which is referred to just once, in eg2.c
.
If the linker adds that reference to your program, and then finds the definition
exported by libz
, the reference is resolved
But when you try to link the program like:
gcc -o eg2 -lz eg2.o
the order of events is wrong in just the same way as with example 1.
At the point when the linker finds -lz
, there are no references to anything
in the program: they are all in eg2.o
, which has not yet been seen. So the
linker decides it has no use for libz
. When it reaches eg2.o
, adds it to the program,
and then has undefined reference to zlibVersion
, the linkage sequence is finished;
that reference is unresolved, and the linkage fails.
Lastly, the pkg-config
variation of example 2 has a now obvious explanation.
After shell-expansion:
gcc -o eg2 $(pkg-config --libs zlib) eg2.o
becomes:
gcc -o eg2 -lz eg2.o
which is just example 2 again.
I can reproduce the problem in example 1, but not in example 2
The linkage:
gcc -o eg2 -lz eg2.o
works just fine for you!
(Or: That linkage worked fine for you on, say, Fedora 23, but fails on Ubuntu 16.04)
That’s because the distro on which the linkage works is one of the ones that
does not configure its GCC toolchain to link shared libraries as-needed.
Back in the day, it was normal for unix-like systems to link static and shared
libraries by different rules. Static libraries in a linkage sequence were linked
on the as-needed basis explained in example 1, but shared libraries were linked unconditionally.
This behaviour is economical at linktime because the linker doesn’t have to ponder
whether a shared library is needed by the program: if it’s a shared library,
link it. And most libraries in most linkages are shared libraries. But there are disadvantages too:-
-
It is uneconomical at runtime, because it can cause shared libraries to be
loaded along with a program even if doesn’t need them. -
The different linkage rules for static and shared libraries can be confusing
to inexpert programmers, who may not know whether-lfoo
in their linkage
is going to resolve to/some/where/libfoo.a
or to/some/where/libfoo.so
,
and might not understand the difference between shared and static libraries
anyway.
This trade-off has led to the schismatic situation today. Some distros have
changed their GCC linkage rules for shared libraries so that the as-needed
principle applies for all libraries. Some distros have stuck with the old
way.
Why do I still get this problem even if I compile-and-link at the same time?
If I just do:
$ gcc -o eg1 -I. -L. -lmy_lib eg1.c
surely gcc has to compile eg1.c
first, and then link the resulting
object file with libmy_lib.a
. So how can it not know that object file
is needed when it’s doing the linking?
Because compiling and linking with a single command does not change the
order of the linkage sequence.
When you run the command above, gcc
figures out that you want compilation +
linkage. So behind the scenes, it generates a compilation command, and runs
it, then generates a linkage command, and runs it, as if you had run the
two commands:
$ gcc -I. -c -o eg1.o eg1.c
$ gcc -o eg1 -L. -lmy_lib eg1.o
So the linkage fails just as it does if you do run those two commands. The
only difference you notice in the failure is that gcc has generated a
temporary object file in the compile + link case, because you’re not telling it
to use eg1.o
. We see:
/tmp/ccQk1tvs.o: In function `main'
instead of:
eg1.o: In function `main':
See also
The order in which interdependent linked libraries are specified is wrong
Putting interdependent libraries in the wrong order is just one way
in which you can get files that need definitions of things coming
later in the linkage than the files that provide the definitions. Putting libraries before the
object files that refer to them is another way of making the same mistake.
Your linkage consumes libraries before the object files that refer to them
- You are trying to compile and link your program with the GCC toolchain.
- Your linkage specifies all of the necessary libraries and library search paths
- If
libfoo
depends onlibbar
, then your linkage correctly putslibfoo
beforelibbar
. - Your linkage fails with
undefined reference to
something errors. - But all the undefined somethings are declared in the header files you have
#include
d and are in fact defined in the libraries that you are linking.
Examples are in C. They could equally well be C++
A minimal example involving a static library you built yourself
my_lib.c
#include "my_lib.h"
#include <stdio.h>
void hw(void)
{
puts("Hello World");
}
my_lib.h
#ifndef MY_LIB_H
#define MT_LIB_H
extern void hw(void);
#endif
eg1.c
#include <my_lib.h>
int main()
{
hw();
return 0;
}
You build your static library:
$ gcc -c -o my_lib.o my_lib.c
$ ar rcs libmy_lib.a my_lib.o
You compile your program:
$ gcc -I. -c -o eg1.o eg1.c
You try to link it with libmy_lib.a
and fail:
$ gcc -o eg1 -L. -lmy_lib eg1.o
eg1.o: In function `main':
eg1.c:(.text+0x5): undefined reference to `hw'
collect2: error: ld returned 1 exit status
The same result if you compile and link in one step, like:
$ gcc -o eg1 -I. -L. -lmy_lib eg1.c
/tmp/ccQk1tvs.o: In function `main':
eg1.c:(.text+0x5): undefined reference to `hw'
collect2: error: ld returned 1 exit status
A minimal example involving a shared system library, the compression library libz
eg2.c
#include <zlib.h>
#include <stdio.h>
int main()
{
printf("%sn",zlibVersion());
return 0;
}
Compile your program:
$ gcc -c -o eg2.o eg2.c
Try to link your program with libz
and fail:
$ gcc -o eg2 -lz eg2.o
eg2.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
collect2: error: ld returned 1 exit status
Same if you compile and link in one go:
$ gcc -o eg2 -I. -lz eg2.c
/tmp/ccxCiGn7.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
collect2: error: ld returned 1 exit status
And a variation on example 2 involving pkg-config
:
$ gcc -o eg2 $(pkg-config --libs zlib) eg2.o
eg2.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
What are you doing wrong?
In the sequence of object files and libraries you want to link to make your
program, you are placing the libraries before the object files that refer to
them. You need to place the libraries after the object files that refer
to them.
Link example 1 correctly:
$ gcc -o eg1 eg1.o -L. -lmy_lib
Success:
$ ./eg1
Hello World
Link example 2 correctly:
$ gcc -o eg2 eg2.o -lz
Success:
$ ./eg2
1.2.8
Link the example 2 pkg-config
variation correctly:
$ gcc -o eg2 eg2.o $(pkg-config --libs zlib)
$ ./eg2
1.2.8
The explanation
Reading is optional from here on.
By default, a linkage command generated by GCC, on your distro,
consumes the files in the linkage from left to right in
commandline sequence. When it finds that a file refers to something
and does not contain a definition for it, to will search for a definition
in files further to the right. If it eventually finds a definition, the
reference is resolved. If any references remain unresolved at the end,
the linkage fails: the linker does not search backwards.
First, example 1, with static library my_lib.a
A static library is an indexed archive of object files. When the linker
finds -lmy_lib
in the linkage sequence and figures out that this refers
to the static library ./libmy_lib.a
, it wants to know whether your program
needs any of the object files in libmy_lib.a
.
There is only object file in libmy_lib.a
, namely my_lib.o
, and there’s only one thing defined
in my_lib.o
, namely the function hw
.
The linker will decide that your program needs my_lib.o
if and only if it already knows that
your program refers to hw
, in one or more of the object files it has already
added to the program, and that none of the object files it has already added
contains a definition for hw
.
If that is true, then the linker will extract a copy of my_lib.o
from the library and
add it to your program. Then, your program contains a definition for hw
, so
its references to hw
are resolved.
When you try to link the program like:
$ gcc -o eg1 -L. -lmy_lib eg1.o
the linker has not added eg1.o
to the program when it sees
-lmy_lib
. Because at that point, it has not seen eg1.o
.
Your program does not yet make any references to hw
: it
does not yet make any references at all, because all the references it makes
are in eg1.o
.
So the linker does not add my_lib.o
to the program and has no further
use for libmy_lib.a
.
Next, it finds eg1.o
, and adds it to be program. An object file in the
linkage sequence is always added to the program. Now, the program makes
a reference to hw
, and does not contain a definition of hw
; but
there is nothing left in the linkage sequence that could provide the missing
definition. The reference to hw
ends up unresolved, and the linkage fails.
Second, example 2, with shared library libz
A shared library isn’t an archive of object files or anything like it. It’s
much more like a program that doesn’t have a main
function and
instead exposes multiple other symbols that it defines, so that other
programs can use them at runtime.
Many Linux distros today configure their GCC toolchain so that its language drivers (gcc
,g++
,gfortran
etc)
instruct the system linker (ld
) to link shared libraries on an as-needed basis.
You have got one of those distros.
This means that when the linker finds -lz
in the linkage sequence, and figures out that this refers
to the shared library (say) /usr/lib/x86_64-linux-gnu/libz.so
, it wants to know whether any references that it has added to your program that aren’t yet defined have definitions that are exported by libz
If that is true, then the linker will not copy any chunks out of libz
and
add them to your program; instead, it will just doctor the code of your program
so that:-
-
At runtime, the system program loader will load a copy of
libz
into the
same process as your program whenever it loads a copy of your program, to run it. -
At runtime, whenever your program refers to something that is defined in
libz
, that reference uses the definition exported by the copy oflibz
in
the same process.
Your program wants to refer to just one thing that has a definition exported by libz
,
namely the function zlibVersion
, which is referred to just once, in eg2.c
.
If the linker adds that reference to your program, and then finds the definition
exported by libz
, the reference is resolved
But when you try to link the program like:
gcc -o eg2 -lz eg2.o
the order of events is wrong in just the same way as with example 1.
At the point when the linker finds -lz
, there are no references to anything
in the program: they are all in eg2.o
, which has not yet been seen. So the
linker decides it has no use for libz
. When it reaches eg2.o
, adds it to the program,
and then has undefined reference to zlibVersion
, the linkage sequence is finished;
that reference is unresolved, and the linkage fails.
Lastly, the pkg-config
variation of example 2 has a now obvious explanation.
After shell-expansion:
gcc -o eg2 $(pkg-config --libs zlib) eg2.o
becomes:
gcc -o eg2 -lz eg2.o
which is just example 2 again.
I can reproduce the problem in example 1, but not in example 2
The linkage:
gcc -o eg2 -lz eg2.o
works just fine for you!
(Or: That linkage worked fine for you on, say, Fedora 23, but fails on Ubuntu 16.04)
That’s because the distro on which the linkage works is one of the ones that
does not configure its GCC toolchain to link shared libraries as-needed.
Back in the day, it was normal for unix-like systems to link static and shared
libraries by different rules. Static libraries in a linkage sequence were linked
on the as-needed basis explained in example 1, but shared libraries were linked unconditionally.
This behaviour is economical at linktime because the linker doesn’t have to ponder
whether a shared library is needed by the program: if it’s a shared library,
link it. And most libraries in most linkages are shared libraries. But there are disadvantages too:-
-
It is uneconomical at runtime, because it can cause shared libraries to be
loaded along with a program even if doesn’t need them. -
The different linkage rules for static and shared libraries can be confusing
to inexpert programmers, who may not know whether-lfoo
in their linkage
is going to resolve to/some/where/libfoo.a
or to/some/where/libfoo.so
,
and might not understand the difference between shared and static libraries
anyway.
This trade-off has led to the schismatic situation today. Some distros have
changed their GCC linkage rules for shared libraries so that the as-needed
principle applies for all libraries. Some distros have stuck with the old
way.
Why do I still get this problem even if I compile-and-link at the same time?
If I just do:
$ gcc -o eg1 -I. -L. -lmy_lib eg1.c
surely gcc has to compile eg1.c
first, and then link the resulting
object file with libmy_lib.a
. So how can it not know that object file
is needed when it’s doing the linking?
Because compiling and linking with a single command does not change the
order of the linkage sequence.
When you run the command above, gcc
figures out that you want compilation +
linkage. So behind the scenes, it generates a compilation command, and runs
it, then generates a linkage command, and runs it, as if you had run the
two commands:
$ gcc -I. -c -o eg1.o eg1.c
$ gcc -o eg1 -L. -lmy_lib eg1.o
So the linkage fails just as it does if you do run those two commands. The
only difference you notice in the failure is that gcc has generated a
temporary object file in the compile + link case, because you’re not telling it
to use eg1.o
. We see:
/tmp/ccQk1tvs.o: In function `main'
instead of:
eg1.o: In function `main':
See also
The order in which interdependent linked libraries are specified is wrong
Putting interdependent libraries in the wrong order is just one way
in which you can get files that need definitions of things coming
later in the linkage than the files that provide the definitions. Putting libraries before the
object files that refer to them is another way of making the same mistake.
Как решить проблему?
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_DeleteGrammarEngine(void *)» (?sol_DeleteGrammarEngine@@YGHPAX@Z) в функции _main
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_CountEntries(void *)» (?sol_CountEntries@@YGHPAX@Z) в функции _main
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «void * __stdcall sol_CreateGrammarEngineW(wchar_t const *)» (?sol_CreateGrammarEngineW@@YGPAXPB_W@Z) в функции _main
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_FindEntry(void *,wchar_t const *,int,int)» (?sol_FindEntry@@YGHPAXPB_WHH@Z) в функции «void __cdecl TestRussian(void *)» (?TestRussian@@YAXPAX@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_DeletePhraseGenerator(void *)» (?sol_DeletePhraseGenerator@@YGHPAX@Z) в функции «void __cdecl TestEnglish(void *)» (?TestEnglish@@YAXPAX@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_DeleteGeneratedPhrase(wchar_t *)» (?sol_DeleteGeneratedPhrase@@YGHPA_W@Z) в функции «void __cdecl TestEnglish(void *)» (?TestEnglish@@YAXPAX@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «wchar_t * __stdcall sol_GeneratePhrase(void *,int,int)» (?sol_GeneratePhrase@@YGPA_WPAXHH@Z) в функции «void __cdecl TestEnglish(void *)» (?TestEnglish@@YAXPAX@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_Paraphrase(void *,int,int,int,int,int,int,int,wchar_t const *,wchar_t *,int,int)» (?sol_Paraphrase@@YGHPAXHHHHHHHPB_WPA_WHH@Z) в функции «void __cdecl TestEnglish(void *)»
(?TestEnglish@@YAXPAX@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_GetVersion(void *,int *,int *,int *)» (?sol_GetVersion@@YGHPAXPAH11@Z) в функции «void __cdecl TestEnglish(void *)» (?TestEnglish@@YAXPAX@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «void * __stdcall sol_CreatePhraseGenerator(void *,int)» (?sol_CreatePhraseGenerator@@YGPAXPAXH@Z) в функции «void __cdecl TestEnglish(void *)» (?TestEnglish@@YAXPAX@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_MatchNGrams(void *,wchar_t const *,int *,int *,int *)» (?sol_MatchNGrams@@YGHPAXPB_WPAH22@Z) в функции «void __cdecl Imitate(wchar_t const *,int)» (?Imitate@@YAXPB_WH@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_LoadKnowledgeBase(void *,wchar_t const *)» (?sol_LoadKnowledgeBase@@YGHPAXPB_W@Z) в функции «void __cdecl Imitate(wchar_t const *,int)» (?Imitate@@YAXPB_WH@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_BuildKnowledgeBase(void *,wchar_t const *,wchar_t const *,int,int)» (?sol_BuildKnowledgeBase@@YGHPAXPB_W1HH@Z) в функции «void __cdecl Imitate(wchar_t const *,int)» (?Imitate@@YAXPB_WH@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_BuildKnowledgeBase2(void *,wchar_t const *,int,int)» (?sol_BuildKnowledgeBase2@@YGHPAXPB_WHH@Z) в функции «void __cdecl Imitate(wchar_t const *,int)» (?Imitate@@YAXPB_WH@Z)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_Set2GramsForPhrase(void *,int,int const *)» (?sol_Set2GramsForPhrase@@YGHPAXHPBH@Z) в функции «void __cdecl TestGenerator(void)» (?TestGenerator@@YAXXZ)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_SetWordsForPhrase(void *,int,int const *,int)» (?sol_SetWordsForPhrase@@YGHPAXHPBHH@Z) в функции «void __cdecl TestGenerator(void)» (?TestGenerator@@YAXXZ)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_StopSynonyms(void *,int,int const *,int)» (?sol_StopSynonyms@@YGHPAXHPBHH@Z) в функции «void __cdecl TestSynonymizer(void)» (?TestSynonymizer@@YAXXZ)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «void __stdcall sol_DeleteProjections(void *)» (?sol_DeleteProjections@@YGXPAX@Z) в функции «void __cdecl TestSynonymizer(void)» (?TestSynonymizer@@YAXXZ)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «int __stdcall sol_GetIEntry(void *,int)» (?sol_GetIEntry@@YGHPAXH@Z) в функции «void __cdecl TestSynonymizer(void)» (?TestSynonymizer@@YAXXZ)
1>fff.obj : error LNK2019: ссылка на неразрешенный внешний символ «void * __stdcall sol_ProjectWord(void *,wchar_t const *,int)» (?sol_ProjectWord@@YGPAXPAXPB_WH@Z) в функции «void __cdecl TestSynonymizer(void)» (?TestSynonymizer@@YAXXZ)
1>C:Users111DesktopfffDebugfff.exe : fatal error LNK1120: 20 неразрешенных внешних элементов
Вот текст программы:
#include «StdAfx.h»
#include <iostream>
#include <vector>
#include <tchar.h>
#include <windows.h>
#include <process.h>
#include <assert.h>
// Grammar Engine API
// API грамматической машины
#include <D:Program Files (x86)SynonymizerSDKincludelemsolarixsynonymizer_engine.h>
#include <D:Program Files (x86)SynonymizerSDKincludelemsolarix_sg_api.h>
using namespace std;
void TestRussian( HFAIND hEngine );
void TestEnglish( HFAIND hEngine );
const int DEF_TIMEOUT = 1000000; // 1000 секунд
static bool exists( const TCHAR *path )
{ return GetFileAttributes(path)!=(DWORD)INVALID_FILE_ATTRIBUTES; }
// **************************************************************
// Вспомогательная процедура — вывод UNICODE текста на консоль
// **************************************************************
static void wide( const wchar_t *ustr )
{
if( ustr==NULL || *ustr==0 )
return;
const int l = wcslen(ustr);
char *abuffer = new char[l+1];
memset( abuffer, 0, l+1 );
WideCharToMultiByte( CP_OEMCP, 0, ustr, l+1, abuffer, l+1, NULL, NULL );
printf( «%s», abuffer );
delete[] abuffer;
return;
}
static HFAIND hEngine = NULL;
static HGREN_PHRASOMAT hFG = NULL;
#if defined TEST_THREADS
unsigned int __stdcall FG_Thread(void*)
{
const wchar_t *words[] = {
L»ПОЛУНОЧИ»,
NULL
};
std::vector<int> ies;
int j=0;
while( words[j]!=NULL )
{
int ie = sol_FindEntry( hEngine, words[j++], NOUN_ru, -1 );
if( ie!=-1 )
ies.push_back(ie);
}
sol_SetWordsForPhrase( hFG, ies.size(), &*ies.begin(), true );
// Сгенерируем парочку предложений с измененным набором слов
for( int i=0; i<1000; i++ )
{
wchar_t *phrase = sol_GeneratePhrase(hFG,0xffffffff,FG_DEBUG);
printf( «#%5d—>», i );
wide(phrase);
printf( «n» );
sol_DeleteGeneratedPhrase(phrase);
}
return 0;
}
#endif
static void Imitate( const wchar_t *src_filename, int language )
{
if( GetFileAttributesW(src_filename)==(DWORD)-1 )
{
return;
}
// генерация квазислучайного текста на основе сведений о матрице переходов,
// создаваемой по исходному тексту.
// Сначала строим матрицу.
int rc1 = sol_BuildKnowledgeBase2( hFG, L»e:\MVoice\lem\scripts\rewriter\путеводитель.txt», 3, 0 );
// Теперь генерация текста.
for( int i=0; i<20; i++ )
{
wchar_t *phrase = sol_GeneratePhrase(
hFG,
FG_GENERATOR_USES_CHAINS,
FG_NO_DEBUG
);
printf( «#%2d «, i );
wide(phrase);
printf( «n» );
sol_DeleteGeneratedPhrase(phrase);
}
// ——————————————————————
// Имитация стиля — строим базу знаний из текста и затем генерируем
// случайный текст на основе информации.
// ——————————————————————
wchar_t tmp_db_folder[MAX_PATH];
swprintf( tmp_db_folder, L»%s\TestKnowledgeBase», _wgetenv(L»TMP») );
CreateDirectoryW( tmp_db_folder, NULL );
// удалим старое содержимое, если оно было.
wchar_t cmdx[MAX_PATH*2];
swprintf( cmdx, L»del /q %s\*.*», tmp_db_folder );
_wsystem( cmdx );
int rc = sol_BuildKnowledgeBase( hEngine, src_filename, tmp_db_folder, language, 0 );
rc = sol_LoadKnowledgeBase( hFG, tmp_db_folder );
for( int i=0; i<20; i++ )
{
wchar_t *phrase = sol_GeneratePhrase(
hFG,
FG_LOGICS | FG_GERUND1
| FG_GERUND2 | FG_COMSENT |
FG_USE_LEX_WHEN_EXHAUSTED
|
FG_DONT_REMOVE_USED |
FG_GENERATOR_USES_NGRAMS,
FG_DEBUG
);
// рассчитываем оценку достоверности фразы по стистическому критерию
int unmatched_2_ngrams=0, n2=0, n3=0;
int rc = sol_MatchNGrams( hEngine, phrase, &unmatched_2_ngrams, &n2, &n3 );
float r=0.0F;
if( (n2+unmatched_2_ngrams)!=0 )
r = float(n2+n3)/float(n2+n3+unmatched_2_ngrams);
printf( «#%2d «, i );
wide(phrase);
printf( » [[%g]]n», r );
sol_DeleteGeneratedPhrase(phrase);
}
return;
}
int main(void)
{
// Грузим морфологию, синтаксис и другие модули.
// Словарь должен быть уже подготовлен и находится в текущем каталоге или одном
// из стандартных для SDK/Integra каталогов. Для подготовки словаря можно запустить
// один из скриптов в sdkscriptsdictionary.
cout << «Loading grammar engine…n»;
bool dict_ok=false;
const TCHAR * paths[] = {
_T(«..\..\..\..\..\..\bin-windows\dictionary.xml»),
_T(«..\..\..\..\..\..\dictionary.xml»),
_T(«dictionary.xml»),
NULL
};
int ipath=0;
while( paths[ipath]!=NULL && dict_ok==false )
{
if( exists(paths[ipath]) )
{
hEngine = sol_CreateGrammarEngine(paths[ipath++]);
if( hEngine!=NULL )
dict_ok=true;
}
}
if( dict_ok )
{
int nentry = sol_CountEntries(hEngine);
cout << «Engine is loaded OKn»;
}
else
{
cout << «Error loading dictionary file ‘diction.xmln»
«You have to download the latest dictionary buildn»
«from http://sourceforge.net/project/solarix»;
return -1;
}
TestRussian(hEngine);
//TestEnglish(hEngine);
// Free allocated resources, delete the engine instance.
sol_DeleteGrammarEngine(hEngine);
cout << «All done.n»;
return 0;
}
static void TestGenerator(void);
static void TestSynonymizer(void);
static void TestParaphraser(void);
static void TestImitator(void);
void TestRussian( HFAIND hEngine )
{
if( sol_FindEntry( hEngine, L»МАМА», /*Solarix::API::*/NOUN_ru, /*Solarix::API::*/RUSSIAN_LANGUAGE )==-1 )
{
cout << «Russian lexicon is missing.n»;
return;
}
TestGenerator();
TestSynonymizer();
// TestParaphraser();
TestImitator();
return;
}
void TestEnglish( HFAIND hEngine )
{
// Проверяем наличие английского лексикона.
if( sol_FindEntry( hEngine, L»MOTHER», /*Solarix::API::*/NOUN_en, /*Solarix::API::*/ENGLISH_LANGUAGE )==-1 )
{
cout << «English lexicon is missing.n»;
return;
}
// Создаем генератор предложений для английского языка
hFG = sol_CreatePhraseGenerator(hEngine,ENGLISH_LANGUAGE);
wchar_t buffer[10001];
memset( buffer, 0, sizeof(buffer) );
bool is_premium = sol_GetVersion( hEngine, NULL, NULL, NULL);
if( is_premium )
{
// Проверяем сложные синонимы (доступно в версии Premium)
const wchar_t *orgs[] =
{
L»I decided to stay»,
L»I’ve decided to stay»,
L»We decide to stay»,
L»He decides to stay»,
L»I am deciding to stay»,
L»You must decide to stay»,
NULL
};
int iorg=0;
while( orgs[iorg]!=NULL )
{
const wchar_t *s = orgs[iorg];
int rc2 = sol_Paraphrase(
hFG,
FG_SYNONYMIZE | FG_SYNONYMIZER_MULTIWORD,
FG_PEDANTIC_ANALYSIS,
FG_NO_NGRAMS,
0,
FG_DEBUG,
FG_YIELD_PLAIN_TEXT,
5,
s,
buffer,
10000,
DEF_TIMEOUT
);
printf( «%s —> «, s );
wide(buffer);
printf( «n» );
iorg++;
}
}
// int rc = sol_Paraphrase( hFG, FG_SYNONYMIZE_OTHERS | FG_SYNONYMIZER_USES_NGRAMS | FG_DEBUG, 5, L»The cat catches the mouse.», buffer, 10000 );
const wchar_t *orgs[] =
{
L»I decided to stay»,
L»The mouse will be surrendering»,
L»The mouse is surrendering»,
L»The jolly mouse», // тут ошибка!
L»The funny mouse»,
L»The mouse surrendered»,
L»is asked»,
L»will be asked»,
L»will be asking»,
L»will be surrendering»,
L»is surrendering»,
L»The mouse surrenders»,
L»The mouse will surrender»,
L»Kitties»,
L»Funny job»,
L»Merry christmas»,
L»Tremendous danger»,
L»Huge disaster»,
L»The mouse gives up.»,
L»The kitty surrendered.»,
L»White cat silently sleeps.»,
L»Black cat catches the moise.»,
NULL
};
int iorg=0;
while( orgs[iorg]!=NULL )
{
const wchar_t *s = orgs[iorg];
int rc = sol_Paraphrase(
hFG,
FG_SYNONYMIZE | FG_SYNONYMIZER_MULTIWORD,
FG_PEDANTIC_ANALYSIS,
FG_NO_NGRAMS,
0,
FG_DEBUG,
FG_YIELD_PLAIN_TEXT,
5,
s,
buffer,
10000,
DEF_TIMEOUT
);
if( wcscmp( s, buffer )==0 )
{
printf( «Error, no synonymization occured for phrase: %sn», s );
}
else
{
printf( «#%d «, iorg );
wide(s);
printf( » —> » );
wide(buffer);
printf( «n» );
}
iorg++;
}
// sol_RandomizePhraseGenerator(hFG);
// Тестируем нефильтрованную по лексике генерацию
for( int i=0; i<30; i++ )
{
wchar_t *phrase = sol_GeneratePhrase(hFG,0,FG_DEBUG);
if( wcsstr( phrase, L»(—» )!=NULL || wcsstr( phrase, L»???» )!=NULL )
{
printf( «Error in phrase generator!n» );
}
printf( «#%2d «, i );
wide(phrase);
printf( «n» );
sol_DeleteGeneratedPhrase(phrase);
}
Imitate( L»..\..\..\..\..\..\scripts\rewriter\etalons-en.txt», ENGLISH_LANGUAGE );
sol_DeletePhraseGenerator(hFG);
Определение:
Данная ошибка означает, что в процессе компоновки программы, компоновщик не смог найти определение некоторой сущности, на которую есть ссылка (попытка использования) в программе.
К таким сущностям может относиться, например, функция или переменная.
Причины и решения:
Возможных причин появления ошибки может быть несколько и это зависит от того, что представляет из себя собираемый проект. Всё множество ситуаций можно разбить на две большие группы:
Используются сторонние библиотеки
-
Не указана необходимая (статическая) библиотека для компоновщика.
Например, к проекту подключен только
*.h
файл с объявлениями, но отсутствует код реализации, обычно это*.lib
или*.a
файлы (в зависимости от используемой системы).
Требуется явно подключить библиотеку к проекту. Для Visual C++ это можно сделать добавлением следующей строки прямо в код:#pragma comment(lib, "libname.lib")
Для
gcc/clang
требуется указать файл через ключ-l
(эль)Для Qt в .pro файле нужно использовать переменную
LIBS
:LIBS += -L[путь_к_библиотеке] -l[имя_библиотеки]
Для системы сборки
cmake
естьtarget_link_libraries
. -
Библиотека указана, но не совпадает разрядность библиотеки и компилируемого кода.
В общем случае, разрядность собираемого проекта (приложения или библиотеки) должна совпадать с разрядностью используемой сторонней библиотеки. Обычно производители библиотек предоставляют возможность выбора 32 или 64 бит версию использовать. Если библиотека поставляется в исходных кодах и собирается отдельно от текущего проекта, нужно также выбрать правильную разрядность.
-
Библиотека указана, но она собрана для другой (не совместимой) ОС.
Например при сборке проекта в Windows осуществляется попытка использовать бинарный файл, собранный для Linux. В данном случае нужно использовать файлы, подходящие для вашей ОС.
-
Библиотека указана, но она собрана другим компилятором, не совместимым с используемым.
Объектные файлы, полученные путем сборки C++ кода разными компиляторами для одной и той же ОС могут быть бинарно несовместимы друг с другом. Требуется использовать совместимые (скорее всего и вовсе одинаковые) компиляторы.
-
Библиотека указана, и собрана тем же компилятором, что и основной проект, но используются разные версии Run-Time библиотек.
Например, для Visual C++ возможна ситуация, когда библиотека собрана с ключом
/MDd
, а основной проект с/MTd
. Требуется задать ключи так, чтобы использовались одинаковые версии Run-Time библиотек.
Сторонние библиотеки не используются
-
Просто отсутствует определение функции.
void f(int); // всего лишь объявление. Нет `тела` функции int main(){ f(42); // undefined reference to `f(int)' }
Требуется добавить определение функции
f
:void f(int) { // тело функции }
Может быть ещё частный случай с ошибкой вида:
undefined reference to `vtable for <имя_класса>`
Такая ошибка возникает, если объявленная виртуальная функция класса, не являющаяся чистой (
=0
), не содержит реализации.class C { virtual void f(int); };
Нужно такую реализацию добавить. Если это делается вне класса, надо не забыть указать имя проблемного класса, иначе это будет просто свободная функция, которая не устраняет указанную проблему:
void C::f(int) { // виртуальная функция-член вне определения класса // тело функции } void f(int) { // свободная функция, не устраняющая проблему // тело функции }
Аналогичная ситуация может возникать при использовании пространств имён, когда объявлении функции находится в пространстве имён:
// В заголовочном файле namespace N { void f(int); };
а при реализации указать это пространство имён забыли:
// В файле реализации void f(int) { // функция в глобальном пространстве имён, не устраняющая проблему // тело функции } namespace N { void f(int) { // функция в нужном пространстве имён // тело функции } } // конец пространства имён
-
Отсутствует определение статической переменной класса.
struct S { static int i; }; int main() { S s; s.i = 42; // undefined reference to `S::i' }
Нужно добавить определение (выделить память) переменной:
int S::i;
-
Неправильная реализация шаблонного кода.
Например, реализация шаблонного кода помещена в
*.cpp
файл, хотя она должна находиться полностью в подключаемом*.h
файле. -
Файл с кодом не был скомпилирован.
Например, в случае использования make-файла не было прописано правило построения файла, а в случае использования IDE типа Visual Studio
*.cpp
файл не добавлен в список файлов проекта. -
Виртуальная функция в базовом классе не объявлена как
=0
(pure-virtual).struct B { void virtual f(); }; struct D : B { void f() {} }; int main() { D d; }
При использовании иерархии классов функция в базовом классе, не имеющая реализации должна быть помечена как «чистая»:
struct B { void virtual f() = 0; };
-
Имя не имеет внешнего связывания.
Например, есть объявление функции
f
в модулеА
и даже ее реализация в модулеB
, но реализация помечена какstatic
:// A.cpp void f(); int main() { f(); // undefined reference to `f()' } // B.cpp static void f() {}
Аналогичная ситуация может возникнуть при использовании безымянного пространства имен:
// B.cpp namespace { void f() {} }
#pragma once
#include «filt1.h»
//#include «filt_gen.h»
//extern void cf(double *h,int hsize,double fs, double f0, double sf, double ef, double *rcf, double *icf);
//extern int filt_gen(double lf,double hf,double* resp);
//extern int differ_gen(double lf,double* resp);
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace ZedGraph;
//static int click;
//static double coordY[4][64], coordX[4][64];
extern double coordY[4][64], coordX[4][64];
extern bool canalOpen[5];
static double l1,l2[5],l3,t;
static short * pbf;
static int per, Canal;
extern int set_generator(int phase,int amplityde, int canal);
extern int set_amp(int att, int gain, int canal);
extern int set_frequency(double frequency, int freq_unit, int canal);
extern int set_compensator(int phase,int amplityde, int canal);
extern int get_amp1();
extern int balance(int canal);
namespace vihretok {
/// <summary>
/// Сводка для Def
///
/// Внимание! При изменении имени этого класса необходимо также изменить
/// свойство имени файла ресурсов («Resource File Name») для средства компиляции управляемого ресурса,
/// связанного со всеми файлами с расширением .resx, от которых зависит данный класс. В противном случае,
/// конструкторы не смогут правильно работать с локализованными
/// ресурсами, сопоставленными данной форме.
/// </summary>
public ref class Def : public System::Windows::Forms::Form
{
public: void Load_Graw (void)
{
// Получим панель для рисования
ZedGraph::GraphPane ^myPane1 = zedGraphControl1—>GraphPane;
// Очистим список кривых на тот случай, если до этого сигналы уже были нарисованы
//myPane1->CurveList->Clear();
//myPane1->GraphObjList->Clear();
//Запрет на самосогласования и выход за установленные границы
myPane1—>XAxis—>Scale—>MaxGrace=0;
myPane1—>XAxis—>Scale—>MinGrace=0;
myPane1—>YAxis—>Scale—>MaxGrace=0;
myPane1—>YAxis—>Scale—>MinGrace=0;
// Подписи к графику и к осям
// Установим размеры шрифтов для подписей по осям
myPane1—>XAxis—>Title—>FontSpec—>Size = 16;
myPane1—>YAxis—>Title—>FontSpec—>Size = 16;
// Установим размеры шрифта для легенды
myPane1—>Legend—>FontSpec—>Size = 12;
// Установим размеры шрифта для общего заголовка
myPane1—>Title—>FontSpec—>Size = 17;
myPane1—>Title—>FontSpec—>FontColor=System::Drawing::Color::Brown;
myPane1—>Title—>Text = «Отклонение по X»;
myPane1—>XAxis—>Title—>Text = «Измерение»;
myPane1—>YAxis—>Title—>Text = «Отклонение»;
//Установка фона панели графиков (не рабочая часть)
myPane1—>Fill—>Color=System::Drawing::Color::LightBlue;
//Установка фона панели отображения графиков
myPane1—>Chart—>Fill = gcnew Fill( Color::White, Color::Aqua, 90 );
//Установка границы вывода графиков
myPane1—>Chart—>Border—>Color=System::Drawing::Color::Black;
// Устанавливаем интересующий нас интервал по оси X
myPane1—>XAxis—>Scale—>Min = l2[Convert::ToInt32(lCanal—>Text)]—2*t;
myPane1—>XAxis—>Scale—>Max = l2[Convert::ToInt32(lCanal—>Text)]+2*t;
//Ручная установка шага оси Х — 1 В
//myPane1->XAxis->Scale->MinorStep = 0.1;
myPane1—>XAxis—>Scale—>MajorStep = 25;
// Устанавливаем интересующий нас интервал по оси Y — значения в мА от -10 до 100 мА
myPane1—>YAxis—>Scale—>Min = —t;
myPane1—>YAxis—>Scale—>Max = t;
//myPane1->YAxis->Scale->MinorStep = 0.1;
myPane1—>YAxis—>Scale—>MajorStep = 25;
//Установка оси «Y» ровно по оси «Х» 0.0
myPane1—>XAxis—>Cross = 0.0;
//Устанавливаем метки только возле осей!
myPane1—>XAxis—>MajorTic—>IsOpposite = false;
myPane1—>XAxis—>MinorTic—>IsOpposite = false;
myPane1—>YAxis—>MajorTic—>IsOpposite = false;
myPane1—>YAxis—>MinorTic—>IsOpposite = false;
//Рисуем сетку по X
myPane1—>XAxis—>MajorGrid—>IsVisible=true;
myPane1—>XAxis—>MajorGrid—>DashOn=20;
myPane1—>XAxis—>MajorGrid—>DashOff=20;
myPane1—>XAxis—>MajorGrid—>Color=System::Drawing::Color::Gray;
myPane1—>XAxis—>Color=System::Drawing::Color::Gray;
//Рисуем сетку по Y
myPane1—>YAxis—>MajorGrid—>IsVisible=true;
myPane1—>YAxis—>MajorGrid—>DashOn=20;
myPane1—>YAxis—>MajorGrid—>DashOff=20;
myPane1—>YAxis—>MajorGrid—>Color=System::Drawing::Color::Gray;
myPane1—>YAxis—>Color=System::Drawing::Color::Gray;
// Получим панель для рисования
ZedGraph::GraphPane ^myPane3 = zedGraphControl3—>GraphPane;
// Очистим список кривых на тот случай, если до этого сигналы уже были нарисованы
//myPane2->CurveList->Clear();
//myPane2->GraphObjList->Clear();
//Запрет на самосогласования и выход за установленные границы
myPane3—>XAxis—>Scale—>MaxGrace=0;
myPane3—>XAxis—>Scale—>MinGrace=0;
myPane3—>YAxis—>Scale—>MaxGrace=0;
myPane3—>YAxis—>Scale—>MinGrace=0;
// Подписи к графику и к осям
// Установим размеры шрифтов для подписей по осям
myPane3—>XAxis—>Title—>FontSpec—>Size = 16;
myPane3—>YAxis—>Title—>FontSpec—>Size = 16;
// Установим размеры шрифта для легенды
myPane3—>Legend—>FontSpec—>Size = 12;
// Установим размеры шрифта для общего заголовка
myPane3—>Title—>FontSpec—>Size = 17;
myPane3—>Title—>FontSpec—>FontColor=System::Drawing::Color::Brown;
myPane3—>Title—>Text = «Отклонение по Z»;
myPane3—>XAxis—>Title—>Text = «Отклонение по Х»;
myPane3—>YAxis—>Title—>Text = «Отклонение по Y»;
//Установка фона панели графиков (не рабочая часть)
myPane3—>Fill—>Color=System::Drawing::Color::LightBlue;
//Установка фона панели отображения графиков
myPane3—>Chart—>Fill = gcnew Fill( Color::White, Color::Aqua, 90 );
//Установка границы вывода графиков
myPane3—>Chart—>Border—>Color=System::Drawing::Color::Black;
// Устанавливаем интересующий нас интервал по оси X
myPane3—>XAxis—>Scale—>Min = —t;
myPane3—>XAxis—>Scale—>Max = t;
//Ручная установка шага оси Х — 1 В
//myPane1->XAxis->Scale->MinorStep = 0.1;
myPane3—>XAxis—>Scale—>MajorStep = 25;
// Устанавливаем интересующий нас интервал по оси Y — значения в мА от -10 до 100 мА
myPane3—>YAxis—>Scale—>Min = —t;
myPane3—>YAxis—>Scale—>Max = t;
//myPane1->YAxis->Scale->MinorStep = 0.1;
myPane3—>YAxis—>Scale—>MajorStep = 25;
//Установка оси «Y» ровно по оси «Х» 0.0
myPane3—>XAxis—>Cross = 0.0;
//Устанавливаем метки только возле осей!
myPane3—>XAxis—>MajorTic—>IsOpposite = false;
myPane3—>XAxis—>MinorTic—>IsOpposite = false;
myPane3—>YAxis—>MajorTic—>IsOpposite = false;
myPane3—>YAxis—>MinorTic—>IsOpposite = false;
//Рисуем сетку по X
myPane3—>XAxis—>MajorGrid—>IsVisible=true;
myPane3—>XAxis—>MajorGrid—>DashOn=20;
myPane3—>XAxis—>MajorGrid—>DashOff=20;
myPane3—>XAxis—>MajorGrid—>Color=System::Drawing::Color::Gray;
myPane3—>XAxis—>Color=System::Drawing::Color::Gray;
//Рисуем сетку по Y
myPane3—>YAxis—>MajorGrid—>IsVisible=true;
myPane3—>YAxis—>MajorGrid—>DashOn=20;
myPane3—>YAxis—>MajorGrid—>DashOff=20;
myPane3—>YAxis—>MajorGrid—>Color=System::Drawing::Color::Gray;
myPane3—>YAxis—>Color=System::Drawing::Color::Gray;
// Получим панель для рисования
ZedGraph::GraphPane ^myPane2 = zedGraphControl2—>GraphPane;
// Очистим список кривых на тот случай, если до этого сигналы уже были нарисованы
//myPane2->CurveList->Clear();
//myPane2->GraphObjList->Clear();
//Запрет на самосогласования и выход за установленные границы
myPane2—>XAxis—>Scale—>MaxGrace=0;
myPane2—>XAxis—>Scale—>MinGrace=0;
myPane2—>YAxis—>Scale—>MaxGrace=0;
myPane2—>YAxis—>Scale—>MinGrace=0;
// Подписи к графику и к осям
// Установим размеры шрифтов для подписей по осям
myPane2—>XAxis—>Title—>FontSpec—>Size = 16;
myPane2—>YAxis—>Title—>FontSpec—>Size = 16;
// Установим размеры шрифта для легенды
myPane2—>Legend—>FontSpec—>Size = 12;
// Установим размеры шрифта для общего заголовка
myPane2—>Title—>FontSpec—>Size = 17;
myPane2—>Title—>FontSpec—>FontColor=System::Drawing::Color::Brown;
myPane2—>Title—>Text = «Отклонение по Y»;
myPane2—>XAxis—>Title—>Text = «Измерение»;
myPane2—>YAxis—>Title—>Text = «Отклонение»;
//Установка фона панели графиков (не рабочая часть)
myPane2—>Fill—>Color=System::Drawing::Color::LightBlue;
//Установка фона панели отображения графиков
myPane2—>Chart—>Fill = gcnew Fill( Color::White, Color::Aqua, 90 );
//Установка границы вывода графиков
myPane2—>Chart—>Border—>Color=System::Drawing::Color::Black;
// Устанавливаем интересующий нас интервал по оси X
myPane2—>XAxis—>Scale—>Min = l2[Convert::ToInt32(lCanal—>Text)]—t*2;
myPane2—>XAxis—>Scale—>Max = l2[Convert::ToInt32(lCanal—>Text)]+t*2;
//Ручная установка шага оси Х — 1 В
//myPane1->XAxis->Scale->MinorStep = 0.1;
myPane2—>XAxis—>Scale—>MajorStep = 25;
// Устанавливаем интересующий нас интервал по оси Y — значения в мА от -10 до 100 мА
myPane2—>YAxis—>Scale—>Min = —t;
myPane2—>YAxis—>Scale—>Max = t;
//myPane1->YAxis->Scale->MinorStep = 0.1;
myPane2—>YAxis—>Scale—>MajorStep = 25;
//Установка оси «Y» ровно по оси «Х» 0.0
myPane2—>XAxis—>Cross = 0.0;
//Устанавливаем метки только возле осей!
myPane2—>XAxis—>MajorTic—>IsOpposite = false;
myPane2—>XAxis—>MinorTic—>IsOpposite = false;
myPane2—>YAxis—>MajorTic—>IsOpposite = false;
myPane2—>YAxis—>MinorTic—>IsOpposite = false;
//Рисуем сетку по X
myPane2—>XAxis—>MajorGrid—>IsVisible=true;
myPane2—>XAxis—>MajorGrid—>DashOn=20;
myPane2—>XAxis—>MajorGrid—>DashOff=20;
myPane2—>XAxis—>MajorGrid—>Color=System::Drawing::Color::Gray;
myPane2—>XAxis—>Color=System::Drawing::Color::Gray;
//Рисуем сетку по Y
myPane2—>YAxis—>MajorGrid—>IsVisible=true;
myPane2—>YAxis—>MajorGrid—>DashOn=20;
myPane2—>YAxis—>MajorGrid—>DashOff=20;
myPane2—>YAxis—>MajorGrid—>Color=System::Drawing::Color::Gray;
myPane2—>YAxis—>Color=System::Drawing::Color::Gray;
//******************************************************************************
// Добавляем информацию по регистрам вывода точек
//******************************************************************************
RollingPointPairList ^list1 = gcnew RollingPointPairList (64);
RollingPointPairList ^list2 = gcnew RollingPointPairList (64);
RollingPointPairList ^list3 = gcnew RollingPointPairList (64);
// Выводим пустые линии графиков на экран
LineItem ^F1Curve = myPane1—>AddCurve( «», list1, Color::Indigo, SymbolType::None);
LineItem ^F2Curve = myPane2—>AddCurve( «», list2, Color::Blue, SymbolType::None);
LineItem ^F3Curve = myPane3—>AddCurve( «», list3, Color::BlueViolet, SymbolType::None);
//Ширина линии в 1/72 дюйма!!!!!!!!!! Хорошо получается при 2!!!!!!!!!
F1Curve—>Line—>Width=2;
F2Curve—>Line—>Width=2;
F3Curve—>Line—>Width=1;
//Задаем что линии гладкии!!!!!!!
F1Curve—>Line—>IsSmooth=true;
F2Curve—>Line—>IsSmooth=true;
F3Curve—>Line—>IsSmooth=true;
// Вызываем метод AxisChange (), чтобы обновить данные об осях.
// В противном случае на рисунке будет показана только часть графика,
// которая умещается в интервалы по осям, установленные по умолчанию
zedGraphControl1—>AxisChange ();
zedGraphControl2—>AxisChange ();
zedGraphControl3—>AxisChange ();
// Обновляем график
zedGraphControl1—>Invalidate();
zedGraphControl2—>Invalidate();
zedGraphControl3—>Invalidate();
}
//График для функций
public: void Graw_Draw (void)
{
//Получаем линии от графиков
LineItem ^F1Curve=(LineItem ^)zedGraphControl1—>GraphPane—>CurveList[0];
LineItem ^F2Curve=(LineItem ^)zedGraphControl2—>GraphPane—>CurveList[0];
LineItem ^F3Curve=(LineItem ^)zedGraphControl3—>GraphPane—>CurveList[0];
IPointListEdit ^list1= (IPointListEdit ^) F1Curve—>Points;
IPointListEdit ^list2= (IPointListEdit ^) F2Curve—>Points;
IPointListEdit ^list3= (IPointListEdit ^) F3Curve—>Points;
//for (unsigned int i=0; i<200; i++)
//{
// int x;
// x=(i-10)*(i-10);
list1—>Add(l2[Convert::ToInt32(lCanal—>Text)], l1);
list2—>Add(l2[Convert::ToInt32(lCanal—>Text)], l3);
list3—>Add(l1, l3);
//}
// Вызываем метод AxisChange (), чтобы обновить данные об осях.
// В противном случае на рисунке будет показана только часть графика,
// которая умещается в интервалы по осям, установленные по умолчанию
zedGraphControl1—>AxisChange ();
zedGraphControl2—>AxisChange ();
zedGraphControl3—>AxisChange();
// Обновляем график
zedGraphControl1—>Invalidate();
zedGraphControl2—>Invalidate();
//************************
}
public:
Def(void)
{
l1=0;
//l2[Canal]=0;
l3=0;
t=5;
InitializeComponent();
//
//TODO: добавьте код конструктора
//
}
protected:
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
~Def()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::TextBox^ tObj;
protected:
private: int click;
private: Devart::Data::MySql::MySqlDataReader^ MySqlDataReader1;
private: System::Windows::Forms::Button^ bSizeMinus;
private: System::Windows::Forms::Button^ bStart;
private: System::Windows::Forms::Button^ bSizePlus;
private: System::Windows::Forms::Label^ lOut;
private: System::Windows::Forms::Label^ lIn;
private: System::Windows::Forms::NumericUpDown^ attIn;
private: System::Windows::Forms::Label^ lPhase;
private: System::Windows::Forms::Timer^ timer1;
private: System::Windows::Forms::Label^ lObj;
private: System::Windows::Forms::NumericUpDown^ attOut;
private: System::Windows::Forms::Label^ lf;
private: System::Windows::Forms::Label^ lAmp;
private: System::Windows::Forms::Button^ bResize;
private: System::Windows::Forms::Label^ lSettings;
private: System::Windows::Forms::TextBox^ tf1;
private: System::Windows::Forms::TextBox^ tPhase1;
private: System::Windows::Forms::TextBox^ tAmp1;
private: System::Windows::Forms::TrackBar^ fBar1;
private: System::Windows::Forms::TrackBar^ phaseBar1;
private: System::Windows::Forms::SplitContainer^ splitContainer1;
private: ZedGraph::ZedGraphControl^ zedGraphControl3;
private: ZedGraph::ZedGraphControl^ zedGraphControl2;
private: ZedGraph::ZedGraphControl^ zedGraphControl1;
private: System::Windows::Forms::Label^ lCanal;
private: Devart::Data::MySql::MySqlConnection^ mySqlConnection1;
private: Devart::Data::MySql::MySqlCommand^ mySqlCommand1;
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::TrackBar^ trackBar1;
private: System::Windows::Forms::Label^ lObject;
private: System::Windows::Forms::Label^ lBase;
private: System::Windows::Forms::Button^ bStop;
private: System::Windows::Forms::Button^ bBalance;
private: System::Windows::Forms::Button^ bFilt;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
#pragma region Windows Form Designer generated code
/// <summary>
/// Обязательный метод для поддержки конструктора — не изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
void InitializeComponent(void)
{
this—>components = (gcnew System::ComponentModel::Container());
System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(Def::typeid));
this—>tObj = (gcnew System::Windows::Forms::TextBox());
this—>bSizeMinus = (gcnew System::Windows::Forms::Button());
this—>bStart = (gcnew System::Windows::Forms::Button());
this—>bSizePlus = (gcnew System::Windows::Forms::Button());
this—>lOut = (gcnew System::Windows::Forms::Label());
this—>lIn = (gcnew System::Windows::Forms::Label());
this—>attIn = (gcnew System::Windows::Forms::NumericUpDown());
this—>lPhase = (gcnew System::Windows::Forms::Label());
this—>timer1 = (gcnew System::Windows::Forms::Timer(this—>components));
this—>lObj = (gcnew System::Windows::Forms::Label());
this—>attOut = (gcnew System::Windows::Forms::NumericUpDown());
this—>lf = (gcnew System::Windows::Forms::Label());
this—>lAmp = (gcnew System::Windows::Forms::Label());
this—>bResize = (gcnew System::Windows::Forms::Button());
this—>lSettings = (gcnew System::Windows::Forms::Label());
this—>tf1 = (gcnew System::Windows::Forms::TextBox());
this—>tPhase1 = (gcnew System::Windows::Forms::TextBox());
this—>tAmp1 = (gcnew System::Windows::Forms::TextBox());
this—>fBar1 = (gcnew System::Windows::Forms::TrackBar());
this—>phaseBar1 = (gcnew System::Windows::Forms::TrackBar());
this—>splitContainer1 = (gcnew System::Windows::Forms::SplitContainer());
this—>bFilt = (gcnew System::Windows::Forms::Button());
this—>bBalance = (gcnew System::Windows::Forms::Button());
this—>bStop = (gcnew System::Windows::Forms::Button());
this—>lBase = (gcnew System::Windows::Forms::Label());
this—>trackBar1 = (gcnew System::Windows::Forms::TrackBar());
this—>label2 = (gcnew System::Windows::Forms::Label());
this—>lCanal = (gcnew System::Windows::Forms::Label());
this—>zedGraphControl3 = (gcnew ZedGraph::ZedGraphControl());
this—>zedGraphControl2 = (gcnew ZedGraph::ZedGraphControl());
this—>zedGraphControl1 = (gcnew ZedGraph::ZedGraphControl());
this—>lObject = (gcnew System::Windows::Forms::Label());
this—>mySqlConnection1 = (gcnew Devart::Data::MySql::MySqlConnection());
this—>mySqlCommand1 = (gcnew Devart::Data::MySql::MySqlCommand());
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>attIn))—>BeginInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>attOut))—>BeginInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>fBar1))—>BeginInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>phaseBar1))—>BeginInit();
this—>splitContainer1—>Panel1—>SuspendLayout();
this—>splitContainer1—>Panel2—>SuspendLayout();
this—>splitContainer1—>SuspendLayout();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>trackBar1))—>BeginInit();
this—>SuspendLayout();
//
// tObj
//
this—>tObj—>Location = System::Drawing::Point(537, 14);
this—>tObj—>Name = L«tObj»;
this—>tObj—>Size = System::Drawing::Size(201, 20);
this—>tObj—>TabIndex = 33;
//
// bSizeMinus
//
this—>bSizeMinus—>Font = (gcnew System::Drawing::Font(L«Microsoft Sans Serif», 12, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this—>bSizeMinus—>Location = System::Drawing::Point(472, 95);
this—>bSizeMinus—>Name = L«bSizeMinus»;
this—>bSizeMinus—>Size = System::Drawing::Size(34, 34);
this—>bSizeMinus—>TabIndex = 32;
this—>bSizeMinus—>Text = L«-«;
this—>bSizeMinus—>UseVisualStyleBackColor = true;
this—>bSizeMinus—>Click += gcnew System::EventHandler(this, &Def::bSizeMinus_Click);
//
// bStart
//
this—>bStart—>BackColor = System::Drawing::SystemColors::ButtonHighlight;
this—>bStart—>Location = System::Drawing::Point(432, 33);
this—>bStart—>Name = L«bStart»;
this—>bStart—>Size = System::Drawing::Size(74, 25);
this—>bStart—>TabIndex = 30;
this—>bStart—>Text = L«СТАРТ»;
this—>bStart—>UseVisualStyleBackColor = true;
this—>bStart—>Click += gcnew System::EventHandler(this, &Def::bStart_Click);
//
// bSizePlus
//
this—>bSizePlus—>Font = (gcnew System::Drawing::Font(L«Microsoft Sans Serif», 12, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this—>bSizePlus—>Location = System::Drawing::Point(432, 95);
this—>bSizePlus—>Name = L«bSizePlus»;
this—>bSizePlus—>Size = System::Drawing::Size(34, 34);
this—>bSizePlus—>TabIndex = 31;
this—>bSizePlus—>Text = L«+»;
this—>bSizePlus—>UseVisualStyleBackColor = true;
this—>bSizePlus—>Click += gcnew System::EventHandler(this, &Def::bSizePlus_Click);
//
// lOut
//
this—>lOut—>AutoSize = true;
this—>lOut—>Location = System::Drawing::Point(32, 95);
this—>lOut—>Name = L«lOut»;
this—>lOut—>Size = System::Drawing::Size(39, 13);
this—>lOut—>TabIndex = 33;
this—>lOut—>Text = L«Выход»;
//
// lIn
//
this—>lIn—>AutoSize = true;
this—>lIn—>Location = System::Drawing::Point(32, 56);
this—>lIn—>Name = L«lIn»;
this—>lIn—>Size = System::Drawing::Size(31, 13);
this—>lIn—>TabIndex = 32;
this—>lIn—>Text = L«Вход»;
//
// attIn
//
this—>attIn—>Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) {3, 0, 0, 0});
this—>attIn—>Location = System::Drawing::Point(29, 72);
this—>attIn—>Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {45, 0, 0, 0});
this—>attIn—>Name = L«attIn»;
this—>attIn—>Size = System::Drawing::Size(45, 20);
this—>attIn—>TabIndex = 30;
this—>attIn—>ValueChanged += gcnew System::EventHandler(this, &Def::attIn_ValueChanged);
//
// lPhase
//
this—>lPhase—>AutoSize = true;
this—>lPhase—>Location = System::Drawing::Point(83, 17);
this—>lPhase—>Name = L«lPhase»;
this—>lPhase—>Size = System::Drawing::Size(36, 13);
this—>lPhase—>TabIndex = 28;
this—>lPhase—>Text = L«Фаза»;
//
// timer1
//
this—>timer1—>Interval = 1;
this—>timer1—>Tick += gcnew System::EventHandler(this, &Def::timer1_Tick);
//
// lObj
//
this—>lObj—>AutoSize = true;
this—>lObj—>Location = System::Drawing::Point(426, 5);
this—>lObj—>Name = L«lObj»;
this—>lObj—>Size = System::Drawing::Size(105, 26);
this—>lObj—>TabIndex = 34;
this—>lObj—>Text = L«Название объекта rnдефектоскопии:»;
//
// attOut
//
this—>attOut—>Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) {3, 0, 0, 0});
this—>attOut—>Location = System::Drawing::Point(29, 109);
this—>attOut—>Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {45, 0, 0, 0});
this—>attOut—>Name = L«attOut»;
this—>attOut—>Size = System::Drawing::Size(45, 20);
this—>attOut—>TabIndex = 31;
this—>attOut—>ValueChanged += gcnew System::EventHandler(this, &Def::attOut_ValueChanged);
//
// lf
//
this—>lf—>AutoSize = true;
this—>lf—>Location = System::Drawing::Point(128, 17);
this—>lf—>Name = L«lf»;
this—>lf—>Size = System::Drawing::Size(49, 13);
this—>lf—>TabIndex = 29;
this—>lf—>Text = L«Частота»;
//
// lAmp
//
this—>lAmp—>AutoSize = true;
this—>lAmp—>Location = System::Drawing::Point(26, 17);
this—>lAmp—>Name = L«lAmp»;
this—>lAmp—>Size = System::Drawing::Size(62, 13);
this—>lAmp—>TabIndex = 27;
this—>lAmp—>Text = L«Амплитуда»;
//
// bResize
//
this—>bResize—>Location = System::Drawing::Point(3, 3);
this—>bResize—>Name = L«bResize»;
this—>bResize—>Size = System::Drawing::Size(22, 22);
this—>bResize—>TabIndex = 26;
this—>bResize—>Text = L«>»;
this—>bResize—>UseVisualStyleBackColor = true;
this—>bResize—>Click += gcnew System::EventHandler(this, &Def::bResize_Click);
//
// lSettings
//
this—>lSettings—>AutoSize = true;
this—>lSettings—>Location = System::Drawing::Point(3, 25);
this—>lSettings—>Name = L«lSettings»;
this—>lSettings—>Size = System::Drawing::Size(15, 117);
this—>lSettings—>TabIndex = 25;
this—>lSettings—>Text = L«НrnАrnСrnТrnРrnОrnЙrnКrnИ»;
this—>lSettings—>TextAlign = System::Drawing::ContentAlignment::TopCenter;
//
// tf1
//
this—>tf1—>Location = System::Drawing::Point(131, 33);
this—>tf1—>Name = L«tf1»;
this—>tf1—>Size = System::Drawing::Size(45, 20);
this—>tf1—>TabIndex = 24;
this—>tf1—>Text = L«500»;
this—>tf1—>TextChanged += gcnew System::EventHandler(this, &Def::tf1_TextChanged);
//
// tPhase1
//
this—>tPhase1—>Location = System::Drawing::Point(80, 33);
this—>tPhase1—>Name = L«tPhase1»;
this—>tPhase1—>Size = System::Drawing::Size(45, 20);
this—>tPhase1—>TabIndex = 23;
this—>tPhase1—>Text = L«0»;
this—>tPhase1—>TextChanged += gcnew System::EventHandler(this, &Def::tPhase1_TextChanged);
//
// tAmp1
//
this—>tAmp1—>Location = System::Drawing::Point(29, 33);
this—>tAmp1—>Name = L«tAmp1»;
this—>tAmp1—>Size = System::Drawing::Size(45, 20);
this—>tAmp1—>TabIndex = 22;
this—>tAmp1—>Text = L«0»;
this—>tAmp1—>TextChanged += gcnew System::EventHandler(this, &Def::tAmp1_TextChanged);
//
// fBar1
//
this—>fBar1—>Location = System::Drawing::Point(131, 60);
this—>fBar1—>Maximum = 1000;
this—>fBar1—>Minimum = 10;
this—>fBar1—>Name = L«fBar1»;
this—>fBar1—>Orientation = System::Windows::Forms::Orientation::Vertical;
this—>fBar1—>Size = System::Drawing::Size(45, 260);
this—>fBar1—>TabIndex = 21;
this—>fBar1—>TickStyle = System::Windows::Forms::TickStyle::Both;
this—>fBar1—>Value = 500;
this—>fBar1—>Scroll += gcnew System::EventHandler(this, &Def::fBar1_Scroll);
//
// phaseBar1
//
this—>phaseBar1—>Location = System::Drawing::Point(80, 60);
this—>phaseBar1—>Maximum = 3600;
this—>phaseBar1—>Name = L«phaseBar1»;
this—>phaseBar1—>Orientation = System::Windows::Forms::Orientation::Vertical;
this—>phaseBar1—>Size = System::Drawing::Size(45, 260);
this—>phaseBar1—>TabIndex = 20;
this—>phaseBar1—>TickStyle = System::Windows::Forms::TickStyle::Both;
this—>phaseBar1—>Scroll += gcnew System::EventHandler(this, &Def::phaseBar1_Scroll);
//
// splitContainer1
//
this—>splitContainer1—>Dock = System::Windows::Forms::DockStyle::Fill;
this—>splitContainer1—>Location = System::Drawing::Point(0, 0);
this—>splitContainer1—>Name = L«splitContainer1»;
//
// splitContainer1.Panel1
//
this—>splitContainer1—>Panel1—>Controls—>Add(this—>lOut);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>lIn);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>attOut);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>attIn);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>lf);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>lPhase);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>lAmp);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>bResize);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>lSettings);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>tf1);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>tPhase1);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>tAmp1);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>fBar1);
this—>splitContainer1—>Panel1—>Controls—>Add(this—>phaseBar1);
this—>splitContainer1—>Panel1MinSize = 28;
//
// splitContainer1.Panel2
//
this—>splitContainer1—>Panel2—>BackColor = System::Drawing::Color::PaleTurquoise;
this—>splitContainer1—>Panel2—>Controls—>Add(this—>bFilt);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>bBalance);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>bStop);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>lBase);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>trackBar1);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>label2);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>lCanal);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>zedGraphControl3);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>zedGraphControl2);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>zedGraphControl1);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>lObj);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>tObj);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>bSizeMinus);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>bSizePlus);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>bStart);
this—>splitContainer1—>Panel2—>Controls—>Add(this—>lObject);
this—>splitContainer1—>Size = System::Drawing::Size(924, 555);
this—>splitContainer1—>SplitterDistance = 28;
this—>splitContainer1—>TabIndex = 5;
//
// bFilt
//
this—>bFilt—>Location = System::Drawing::Point(432, 135);
this—>bFilt—>Name = L«bFilt»;
this—>bFilt—>Size = System::Drawing::Size(72, 23);
this—>bFilt—>TabIndex = 45;
this—>bFilt—>Text = L«Фильтр»;
this—>bFilt—>UseVisualStyleBackColor = true;
this—>bFilt—>Click += gcnew System::EventHandler(this, &Def::bFilt_Click);
//
// bBalance
//
this—>bBalance—>Location = System::Drawing::Point(432, 164);
this—>bBalance—>Name = L«bBalance»;
this—>bBalance—>Size = System::Drawing::Size(73, 23);
this—>bBalance—>TabIndex = 44;
this—>bBalance—>Text = L«Баланс»;
this—>bBalance—>UseVisualStyleBackColor = true;
this—>bBalance—>Click += gcnew System::EventHandler(this, &Def::bBalance_Click);
//
// bStop
//
this—>bStop—>BackColor = System::Drawing::SystemColors::ButtonHighlight;
this—>bStop—>Location = System::Drawing::Point(432, 64);
this—>bStop—>Name = L«bStop»;
this—>bStop—>Size = System::Drawing::Size(74, 25);
this—>bStop—>TabIndex = 43;
this—>bStop—>Text = L«СТОП»;
this—>bStop—>UseVisualStyleBackColor = true;
this—>bStop—>Click += gcnew System::EventHandler(this, &Def::bStop_Click);
//
// lBase
//
this—>lBase—>AutoSize = true;
this—>lBase—>Location = System::Drawing::Point(565, 99);
this—>lBase—>Name = L«lBase»;
this—>lBase—>Size = System::Drawing::Size(33, 13);
this—>lBase—>TabIndex = 42;
this—>lBase—>Text = L«lBase»;
this—>lBase—>Visible = false;
//
// trackBar1
//
this—>trackBar1—>BackColor = System::Drawing::Color::PaleTurquoise;
this—>trackBar1—>Location = System::Drawing::Point(3, 498);
this—>trackBar1—>Name = L«trackBar1»;
this—>trackBar1—>Size = System::Drawing::Size(666, 45);
this—>trackBar1—>TabIndex = 40;
this—>trackBar1—>TickStyle = System::Windows::Forms::TickStyle::None;
this—>trackBar1—>Visible = false;
this—>trackBar1—>Scroll += gcnew System::EventHandler(this, &Def::trackBar1_Scroll);
//
// label2
//
this—>label2—>AutoSize = true;
this—>label2—>Location = System::Drawing::Point(564, 81);
this—>label2—>Name = L«label2»;
this—>label2—>Size = System::Drawing::Size(35, 13);
this—>label2—>TabIndex = 39;
this—>label2—>Text = L«label1»;
this—>label2—>Visible = false;
//
// lCanal
//
this—>lCanal—>AutoSize = true;
this—>lCanal—>Location = System::Drawing::Point(564, 62);
this—>lCanal—>Name = L«lCanal»;
this—>lCanal—>Size = System::Drawing::Size(35, 13);
this—>lCanal—>TabIndex = 38;
this—>lCanal—>Text = L«label1»;
this—>lCanal—>Visible = false;
//
// zedGraphControl3
//
this—>zedGraphControl3—>Location = System::Drawing::Point(429, 246);
this—>zedGraphControl3—>Name = L«zedGraphControl3»;
this—>zedGraphControl3—>ScrollGrace = 0;
this—>zedGraphControl3—>ScrollMaxX = 0;
this—>zedGraphControl3—>ScrollMaxY = 0;
this—>zedGraphControl3—>ScrollMaxY2 = 0;
this—>zedGraphControl3—>ScrollMinX = 0;
this—>zedGraphControl3—>ScrollMinY = 0;
this—>zedGraphControl3—>ScrollMinY2 = 0;
this—>zedGraphControl3—>Size = System::Drawing::Size(240, 240);
this—>zedGraphControl3—>TabIndex = 37;
//
// zedGraphControl2
//
this—>zedGraphControl2—>Location = System::Drawing::Point(3, 246);
this—>zedGraphControl2—>Name = L«zedGraphControl2»;
this—>zedGraphControl2—>ScrollGrace = 0;
this—>zedGraphControl2—>ScrollMaxX = 0;
this—>zedGraphControl2—>ScrollMaxY = 0;
this—>zedGraphControl2—>ScrollMaxY2 = 0;
this—>zedGraphControl2—>ScrollMinX = 0;
this—>zedGraphControl2—>ScrollMinY = 0;
this—>zedGraphControl2—>ScrollMinY2 = 0;
this—>zedGraphControl2—>Size = System::Drawing::Size(420, 240);
this—>zedGraphControl2—>TabIndex = 36;
//
// zedGraphControl1
//
this—>zedGraphControl1—>Location = System::Drawing::Point(3, 5);
this—>zedGraphControl1—>Name = L«zedGraphControl1»;
this—>zedGraphControl1—>ScrollGrace = 0;
this—>zedGraphControl1—>ScrollMaxX = 0;
this—>zedGraphControl1—>ScrollMaxY = 0;
this—>zedGraphControl1—>ScrollMaxY2 = 0;
this—>zedGraphControl1—>ScrollMinX = 0;
this—>zedGraphControl1—>ScrollMinY = 0;
this—>zedGraphControl1—>ScrollMinY2 = 0;
this—>zedGraphControl1—>Size = System::Drawing::Size(420, 240);
this—>zedGraphControl1—>TabIndex = 35;
//
// lObject
//
this—>lObject—>AutoSize = true;
this—>lObject—>Location = System::Drawing::Point(537, 18);
this—>lObject—>Name = L«lObject»;
this—>lObject—>Size = System::Drawing::Size(0, 13);
this—>lObject—>TabIndex = 41;
//
// mySqlConnection1
//
this—>mySqlConnection1—>ConnectionString = L«User Id=root;Host=localhost;Database=fazus_db;»;
this—>mySqlConnection1—>Name = L«mySqlConnection1»;
//
// mySqlCommand1
//
this—>mySqlCommand1—>Connection = this—>mySqlConnection1;
this—>mySqlCommand1—>Name = L«mySqlCommand1»;
//
// Def
//
this—>AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this—>AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this—>BackColor = System::Drawing::Color::PaleTurquoise;
this—>ClientSize = System::Drawing::Size(924, 555);
this—>Controls—>Add(this—>splitContainer1);
this—>Icon = (cli::safe_cast<System::Drawing::Icon^ >(resources—>GetObject(L«$this.Icon»)));
this—>Name = L«Def»;
this—>Text = L«Def»;
this—>Load += gcnew System::EventHandler(this, &Def::Def_Load);
this—>VisibleChanged += gcnew System::EventHandler(this, &Def::Def_Load);
this—>FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &Def::Def_FormClosing);
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>attIn))—>EndInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>attOut))—>EndInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>fBar1))—>EndInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>phaseBar1))—>EndInit();
this—>splitContainer1—>Panel1—>ResumeLayout(false);
this—>splitContainer1—>Panel1—>PerformLayout();
this—>splitContainer1—>Panel2—>ResumeLayout(false);
this—>splitContainer1—>Panel2—>PerformLayout();
this—>splitContainer1—>ResumeLayout(false);
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this—>trackBar1))—>EndInit();
this—>ResumeLayout(false);
}
#pragma endregion
private: System::Void Def_Load(System::Object^ sender, System::EventArgs^ e) {
tPhase1—>Text=Convert::ToString((float)phaseBar1—>Value/10);
tf1—>Text=Convert::ToString(fBar1—>Value);
click=0;
/* fd_set soc_insp;
timeval insp_time;
soc_insp.fd_count = 1;
soc_insp.fd_array[0] = m_sock;
insp_time.tv_sec = 0;
insp_time.tv_usec = 10000*2;*/
/* init_program();
init_instrument();
select(0, &soc_insp, NULL, NULL, &insp_time);
this->Name;*/
if(this—>Name==«Can0») {
Canal=0;
lCanal—>Text=«0»;
this—>Text=«Дефектоскопия, канал 1»;
}
if(this—>Name==«Can1») {
Canal=1;
lCanal—>Text=«1»;
this—>Text=«Дефектоскопия, канал 2»;
}
if(this—>Name==«Can2») {
Canal=2;
lCanal—>Text=«2»;
this—>Text=«Дефектоскопия, канал 3»;
}
if(this—>Name==«Can3») {
Canal=3;
lCanal—>Text=«3»;
this—>Text=«Дефектоскопия, канал 4»;
}
if(this—>Name!=«Can0»&&this—>Name!=«Can1»&&this—>Name!=«Can2»&&this—>Name!=«Can3») {
Canal=99;
l2[4]=0;
trackBar1—>Value=(int)l2[4];
lCanal—>Text=«4»;
bBalance—>Visible=false;
lBase—>Text=this—>Name;
tObj—>Visible=false;
bResize—>Visible=false;
lSettings—>Visible=false;
bFilt—>Visible=false;
this—>Text=«Дефектоскопия, архив»;
trackBar1—>Visible=true;
mySqlCommand1—>CommandText=«select X from`»+lBase—>Text+«`;»;
mySqlConnection1—>Open();
MySqlDataReader1 = mySqlCommand1—>ExecuteReader();
while(MySqlDataReader1—>Read())
{
}
trackBar1—>Maximum=Convert::ToInt16(MySqlDataReader1—>RecordCount::get());
mySqlCommand1—>CommandText=«select `obj` from`obj` where `database`='»+lBase—>Text+«‘;»;
MySqlDataReader1 = mySqlCommand1—>ExecuteReader();
while(MySqlDataReader1—>Read())
{
for (int i = 0; i < MySqlDataReader1—>FieldCount; i++)
{
lObject—>Text=MySqlDataReader1—>GetValue(i)—>ToString();
}
}
mySqlConnection1—>Close();
}
canalOpen[Convert::ToInt32(lCanal—>Text)]=false;
this—>Load_Graw();
}
private: System::Void tAmp1_TextChanged(System::Object^ sender, System::EventArgs^ e) {
set_generator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_compensator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_amp(Convert::ToInt32(attIn—>Text)/3,Convert::ToInt32(attOut—>Text)/3,Convert::ToInt32(lCanal—>Text));
set_frequency(fBar1—>Value,1,Convert::ToInt32(lCanal—>Text));
}
private: System::Void tf1_TextChanged(System::Object^ sender, System::EventArgs^ e) {
fBar1—>Value=Convert::ToInt32(tf1—>Text);
set_frequency(fBar1—>Value,1,Convert::ToInt32(lCanal—>Text));
}
private: System::Void tPhase1_TextChanged(System::Object^ sender, System::EventArgs^ e) {
set_generator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_compensator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_amp(Convert::ToInt32(attIn—>Text)/3,Convert::ToInt32(attOut—>Text)/3,Convert::ToInt32(lCanal—>Text));
set_frequency(fBar1—>Value,1,Convert::ToInt32(lCanal—>Text));
}
private: System::Void phaseBar1_Scroll(System::Object^ sender, System::EventArgs^ e) {
tPhase1—>Text=Convert::ToString((float)phaseBar1—>Value/10);
}
private: System::Void fBar1_Scroll(System::Object^ sender, System::EventArgs^ e) {
tf1—>Text=Convert::ToString(fBar1—>Value);
}
private: System::Void bResize_Click(System::Object^ sender, System::EventArgs^ e) {
click++;
if(click%2){
splitContainer1—>SplitterDistance=tf1—>Width+tf1—>Left+3;
bResize—>Text=«<«;
}
else{
splitContainer1—>SplitterDistance=bResize—>Width;
bResize—>Text=«>»;
}
}
private: System::Void attIn_ValueChanged(System::Object^ sender, System::EventArgs^ e) {
tAmp1—>Text=Convert::ToString(get_amp1());
set_generator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_compensator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_amp(Convert::ToInt32(attIn—>Text)/3,Convert::ToInt32(attOut—>Text)/3,Convert::ToInt32(lCanal—>Text));
}
private: System::Void attOut_ValueChanged(System::Object^ sender, System::EventArgs^ e) {
tAmp1—>Text=Convert::ToString(get_amp1());
set_generator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_compensator(phaseBar1—>Value,Convert::ToInt32(tAmp1—>Text),Convert::ToInt32(lCanal—>Text));
set_amp(Convert::ToInt32(attIn—>Text)/3,Convert::ToInt32(attOut—>Text)/3,Convert::ToInt32(lCanal—>Text));
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
if(this—>Name!=«Can0»&&this—>Name!=«Can1»&&this—>Name!=«Can2»&&this—>Name!=«Can3»)
{//алгоритм вывода из базы
if(lObject—>Text!=«»){
int z;
l2[4]=trackBar1—>Value;
if(trackBar1—>Value<64){
z=0;
}
else{
z=trackBar1—>Value—64;
}
timer1—>Interval=42;
//timer1->Interval=65;
//timer1->Interval=1;
l2[4]=++l2[4];
trackBar1—>Value=Convert::ToInt32(l2[4]);
if(l2[4]>trackBar1—>Maximum—2){
timer1—>Enabled=false;
}
mySqlCommand1—>CommandText = «select `X` from`»+lBase—>Text+«` where `id`=»+trackBar1—>Value+«;»;
mySqlConnection1—>Open();
MySqlDataReader1 = mySqlCommand1—>ExecuteReader();
while(MySqlDataReader1—>Read())
{
for (int i = 0; i < MySqlDataReader1—>FieldCount; i++)
{
l1=Convert::ToDouble(MySqlDataReader1—>GetValue(i)—>ToString());
if(l2[4]>trackBar1—>Maximum—2){
break;
timer1—>Enabled=false;
}
per++;
if(per>=64){
per=0;};
if(l1>t) t=t+2.5;
if(l3>t) t=t+2.5;
if(l1<—t) t=t+2.5;
if(l3<—t) t=t+2.5;
}
}
mySqlCommand1—>CommandText = «select `Y` from`»+lBase—>Text+«` where `id`=»+trackBar1—>Value+«;»;
mySqlConnection1—>Open();
MySqlDataReader1 = mySqlCommand1—>ExecuteReader();
while(MySqlDataReader1—>Read())
{
for (int i = 0; i < MySqlDataReader1—>FieldCount; i++)
{
l3=Convert::ToDouble(MySqlDataReader1—>GetValue(i)—>ToString());
if(l2[4]>trackBar1—>Maximum—2){
break;
timer1—>Enabled=false;
}
per++;
if(per>=64){
per=0;};
if(l1>t) t=t+2.5;
if(l3>t) t=t+2.5;
if(l1<—t) t=t+2.5;
if(l3<—t) t=t+2.5;
}
}
Load_Graw();
Graw_Draw();
mySqlConnection1—>Close();
}
}
else
{
l1=coordX[Convert::ToInt32(lCanal—>Text)][per]/1000;
l3=coordY[Convert::ToInt32(lCanal—>Text)][per]/1000;
this—>Load_Graw();
this—>Graw_Draw();
l2[Convert::ToInt32(lCanal—>Text)]=++l2[Convert::ToInt32(lCanal—>Text)];
mySqlCommand1—>CommandText = «insert into `»+label2—>Text+«`(`X`,`Y`) values (‘»+Convert::ToString(l1)+«‘,'»+Convert::ToString(l3)+«‘);»;
mySqlConnection1—>Open();
mySqlCommand1—>ExecuteNonQuery();
per++;
if(per>=64){
per=0;};
if(l1>t) t=t+2.5;
if(l3>t) t=t+2.5;
if(l1<—t) t=t+2.5;
if(l3<—t) t=t+2.5;
}
}
private: System::Void bStart_Click(System::Object^ sender, System::EventArgs^ e) {
if((tObj—>Text!=«»)&&(tObj—>Text!=«Enter the name of the object inspection»)&&(this—>Name==«Can0»||this—>Name==«Can1»||this—>Name==«Can2»||this—>Name==«Can3»)){
timer1—>Interval=1;
DateTime date1;
date1=DateTime::Now;
mySqlCommand1—>CommandText = «create table `»+Convert::ToString(date1.Day)+«_»+Convert::ToString(date1.Month)+«_»+Convert::ToString(date1.Year)+«_»+Convert::ToString(date1.Hour)+«_»+Convert::ToString(date1.Minute)+«_»+Convert::ToString(date1.Second)+«`(`ID` int(10) AUTO_INCREMENT,`X` char(10),`Y` char(10), `step` int(10), PRIMARY KEY(`ID`));»;
mySqlConnection1—>Open();
label2—>Text=Convert::ToString(date1.Day)+«_»+Convert::ToString(date1.Month)+«_»+Convert::ToString(date1.Year)+«_»+Convert::ToString(date1.Hour)+«_»+Convert::ToString(date1.Minute)+«_»+Convert::ToString(date1.Second);
mySqlCommand1—>ExecuteNonQuery();
mySqlCommand1—>CommandText = «insert into `obj`(`OBJ`,`database`) values (‘»+tObj—>Text+«‘,'»+label2—>Text+«‘);»;
mySqlCommand1—>ExecuteNonQuery();
timer1—>Enabled=true;
mySqlConnection1—>Close();
}
else
{
tObj—>Text=«Enter the name of the object inspection»;
}
if((lObject—>Text!=«»)&&(trackBar1—>Value<trackBar1—>Maximum—2)){
timer1—>Enabled=true;
l2[4]=trackBar1—>Value;
}
/* if(lObject->Text!=»»){
int z;
l2[4]=trackBar1->Value;
if(trackBar1->Value<64){
z=0;
}
else{
z=trackBar1->Value-64;
}
mySqlCommand1->CommandText = «select `X` from`»+lBase->Text+»` where `id`<«+trackBar1->Value+» and `id`>=»+z+»;»;
mySqlConnection1->Open();
MySqlDataReader1 = mySqlCommand1->ExecuteReader();
while(MySqlDataReader1->Read())
{
for (int i = 0; i < MySqlDataReader1->FieldCount; i++)
{
l1=Convert::ToDouble(MySqlDataReader1->GetValue(i)->ToString());
l2[4]=++l2[4];
trackBar1->Value=Convert::ToInt32(l2[4]);
per++;
if(per>=64){
per=0;};
if(l1>t) t=t+2.5;
if(l3>t) t=t+2.5;
if(l1<-t) t=t+2.5;
if(l3<-t) t=t+2.5;
}
}
mySqlConnection1->Close();
timer1->Enabled=true;*/
// }
}
private: System::Void bSizePlus_Click(System::Object^ sender, System::EventArgs^ e) {
t=t—2.5;
}
private: System::Void bSizeMinus_Click(System::Object^ sender, System::EventArgs^ e) {
t=t+2.5;
}
private: System::Void trackBar1_Scroll(System::Object^ sender, System::EventArgs^ e) {
if(!timer1—>Enabled){
int z;
l2[4]=trackBar1—>Value;
if(trackBar1—>Value<64){
z=0;
}
else{
z=trackBar1—>Value—64;
}
l2[4]=++l2[4];
mySqlCommand1—>CommandText = «select `X` from`»+lBase—>Text+«` where `id`<«+trackBar1—>Value+» and `id`>»+z+«;»;
mySqlConnection1—>Open();
MySqlDataReader1 = mySqlCommand1—>ExecuteReader();
while(MySqlDataReader1—>Read())
{
for (int i = 0; i < MySqlDataReader1—>FieldCount; i++)
{
l1=Convert::ToDouble(MySqlDataReader1—>GetValue(i)—>ToString());
per++;
if(per>=64){
per=0;};
if(l1>t) t=t+2.5;
if(l3>t) t=t+2.5;
if(l1<—t) t=t+2.5;
if(l3<—t) t=t+2.5;
}
}
mySqlCommand1—>CommandText = «select `Y` from`»+lBase—>Text+«` where `id`=»+trackBar1—>Value+«;»;
mySqlConnection1—>Open();
MySqlDataReader1 = mySqlCommand1—>ExecuteReader();
while(MySqlDataReader1—>Read())
{
for (int i = 0; i < MySqlDataReader1—>FieldCount; i++)
{
l3=Convert::ToDouble(MySqlDataReader1—>GetValue(i)—>ToString());
per++;
if(per>=64){
per=0;};
if(l1>t) t=t+2.5;
if(l3>t) t=t+2.5;
if(l1<—t) t=t+2.5;
if(l3<—t) t=t+2.5;
}
}
Load_Graw();
Graw_Draw();
mySqlConnection1—>Close();
}
}
private: System::Void bStop_Click(System::Object^ sender, System::EventArgs^ e) {
timer1—>Enabled=false;
}
private: System::Void bBalance_Click(System::Object^ sender, System::EventArgs^ e) {
balance(Convert::ToInt32(lCanal—>Text));
}
private: System::Void bFilt_Click(System::Object^ sender, System::EventArgs^ e) {
filt1^ gfilt = gcnew filt1;
gfilt—>Show();
}
private: System::Void Def_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e) {
canalOpen[Convert::ToInt32(lCanal—>Text)]=true;
}
};
}
//Convert::ToInt32(lCanal)
/* mySqlInsertData->CommandText = «insert into `»+label2->Text+»`(`X`,`Y`, `step`) values (‘»+textBox1->Text+»‘,'»+textBox2->Text+»‘,'»+textBox3->Text+»‘);»;
label1->Text=mySqlInsertData->CommandText;
mySqlInsertData->ExecuteNonQuery();
*/