Russian Qt Forum
Сентябрь 22, 2024, 23:33 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Тупая, нелогичная ошибка [Решено]  (Прочитано 7869 раз)
CJ1
Гость
« : Сентябрь 08, 2012, 10:38 »

У меня есть файл test.h
Код:
#ifndef TEST_H
#define TEST_H

#include <d3dx11.h>
#include <QtGui/QMainWindow>
#include <QTimer>
#include <xnamath.h>
#include <dinput.h>
#include "DIMPUT.h"
#include <QLIST>

struct ConstantBuffer
{
    XMMATRIX mWorld;              // Матрица мира
    XMMATRIX mView;        // Матрица вида
    XMMATRIX mProjection;  // Матрица проекции
};

#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p)      { if (p) { (p)->Release(); (p)=NULL; } }
#endif

DEFINE_GUID(DIGUID, 0xd1e5da1b, 0x64dc, 0x41ae, 0xbc, 0xa9, 0x5a, 0xfc, 0xf9, 0x29, 0x77, 0xcc);

enum {
MOUSE_X,
MOUSE_Y,
MOUSE_L,
MOUSE_R,
MOUSE_C,
NumEnum,
};

DIACTION action_[] =
{
{VK_LEFT, DIKEYBOARD_LEFT,0,L"Влево"},
{MOUSE_Y, DIMOUSE_YAXIS, 0, L"Мышка по Y"},
{MOUSE_X, DIMOUSE_XAXIS, 0, L"Мышка по X"},
{MOUSE_L, DIMOUSE_BUTTON0, 0, L"Кнопка мыши левая"},



};

typedef struct DeviceDI
{
IDirectInputDevice8 *pDIDevice;
bool Axsis;
bool Mapped[ARRAYSIZE(action_)];
int Imput[ARRAYSIZE(action_)];
} DeviceDI;







class test : public QMainWindow
{
Q_OBJECT

public:
test(QWidget *parent = 0, Qt::WFlags flags = 0);
~test();
bool getError();
void AddDevice(LPCDIDEVICEINSTANCE, LPDIRECTINPUTDEVICE8);

private:
BOOL InitializeDirect3d11App();
void ReleaseObjects();
bool InitScene();
void initImput();
//BOOL CALLBACK EnumDevices(LPCDIDEVICEINSTANCE pdInst,            LPVOID pvRef);


private slots:
void DrawScene();
void PrintFPS();

protected:
virtual void keyPressEvent(QKeyEvent *);
virtual void mouseMoveEvent(QMouseEvent*);

private:

float m;
struct Vertex
{

XMFLOAT3 pos;
XMFLOAT2 tex;
Vertex(float x, float y, float z, float tx, float ty) : pos(x,y,z), tex(tx, ty){}
};

int FPS;
QTimer t;
QTimer RenderTimer;
bool error;

IDXGISwapChain* SwapChain;
ID3D11Device* Device;
ID3D11DeviceContext* DeviceContext;
ID3D11RenderTargetView* RenderTargetView;
ID3D11Buffer* VertexBuffer;
ID3D11Buffer* IndexBuffer;
ID3D11VertexShader* VS;
ID3D11PixelShader* PS;
ID3D10Blob* VS_Buffer;
ID3D10Blob* PS_Buffer;
ID3D11InputLayout* vertLayout;
ID3D11ShaderResourceView* colorMap_;
ID3D11SamplerState* colorMapSampler_;
D3D11_VIEWPORT viewport;
ID3D11Buffer* g_pConstantBuffer;           // Константный буфер

ID3D11RasterizerState * RasterizerState;

XMMATRIX                g_World;                      // Матрица мира
XMMATRIX                g_View;                       // Матрица вида
XMMATRIX                g_Projection;                 // Матрица проекции

IDirectInput8 * DirectInput;
QList<DeviceDI> DevID;
};

#endif // TEST_H


Почему линкер ругается вот так?

1>  qrc_test.cpp
1>main.obj : error LNK2005: "struct _DIACTIONW * action_" (?action_@@3PAU_DIACTIONW@@A) уже определен в moc_test.obj
1>test.obj : error LNK2005: "struct _DIACTIONW * action_" (?action_@@3PAU_DIACTIONW@@A) уже определен в moc_test.obj
1>D:\test qt\test\Win32\Debug\\test.exe : fatal error LNK1169: обнаружен многократно определенный символ - один или более
1>
1>СБОЙ построения.


« Последнее редактирование: Сентябрь 09, 2012, 16:55 от CJ1 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Сентябрь 08, 2012, 12:06 »

Код
C++ (Qt)
// test.h
DIACTION action_[];   // предварительное описание
 
// test.cpp или в любом cpp
DIACTION action_[] =   // полное описание
{
{VK_LEFT, DIKEYBOARD_LEFT,0,L"Влево"},
...
};
 
Разрешается любое кол-во предварительных описаний, но только одно полное

Записан
CJ1
Гость
« Ответ #2 : Сентябрь 08, 2012, 18:07 »

Странно! Почему так?
Да, так работает! Но... я видимо что-то пропустил, когда синтаксис изучал C++
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Сентябрь 08, 2012, 18:55 »

Странно! Почему так?
Да, так работает! Но... я видимо что-то пропустил, когда синтаксис изучал C++
#include имеет тот же эффект как если бы Вы тело h-файла написали (просто подстановка). Если test.h включен в 2 или более cpp, в каждом из них объявлена глобальная action_, о чем Вам и поведал линкер
Записан
CJ1
Гость
« Ответ #4 : Сентябрь 08, 2012, 20:01 »

Понятно!
Но я думал если написать
#ifndef TEST_H
#define TEST_H

То он объявит только один раз
Записан
Serr500
Гость
« Ответ #5 : Сентябрь 08, 2012, 20:12 »

Это защита от повторных включений в один файл, а не в разные.
Например:
Код:
file1.h:
#ifndef FILE1_H
.....
#endif


file2.h:
#ifndef FILE2_H
#define FILE2_H
#include "file1.hpp"
.....
#endif


file3.h:
#ifndef FILE3_H
#define FILE3_H
#include "file1.hpp"
.....
#endif


file.cpp:
#include "file1.h"
#include "file2.h"
.....
Если бы не было стражей включения, то в file.cpp все конструкции из file1.h вставились бы дважды, что с большой вероятностью привело бы к ошибкам компиляции (повторное определение типов и т.д.). Но если добавить ещё один файл
Код:
fileN.cpp:
#include "file1.h"
.....
то в него будет включено всё содержимое из "file1.h".
Проще говоря, все дефайны локальны для каждой единицы компиляции, а .cpp-файл и является такой единицей. (Глобальные дефайны можно определить в .pro-файле.)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Сентябрь 08, 2012, 20:38 »

Понятно!
А если так ?
Код
C++ (Qt)
// test.h
static DIACTION action_[] =  
{
{VK_LEFT, DIKEYBOARD_LEFT,0,L"Влево"},
...
};
 
  Улыбающийся
Записан
Krysk
Гость
« Ответ #7 : Сентябрь 09, 2012, 05:05 »

Так инициализировать можно только константы...

Читай про "инстанцирование" выносишь инициализацию в x.сpp а в заголовке объявляешь переменную extern DIACTION action_[];
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Сентябрь 09, 2012, 09:50 »

Так инициализировать можно только константы...

Читай про "инстанцирование" выносишь инициализацию в x.сpp а в заголовке объявляешь переменную extern DIACTION action_[];
Не стоит полагать что любой задающий вопрос есть безграмотный лох, типа "спрашивает - значит не знает"  Улыбающийся
Записан
CJ1
Гость
« Ответ #9 : Сентябрь 09, 2012, 16:55 »

Понятно!
А если так ?
Код
C++ (Qt)
// test.h
static DIACTION action_[] =  
{
{VK_LEFT, DIKEYBOARD_LEFT,0,L"Влево"},
...
};
 
  Улыбающийся

Так работает! Все разобрался я! Спасибо!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Сентябрь 09, 2012, 17:41 »

Код
C++ (Qt)
// test.h
static DIACTION action_[] =  
 
Так работает! Все разобрался я! Спасибо!
Так "компилится", но работает совсем не так как надо  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.27 секунд. Запросов: 23.