Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Проблемы подключения файлов


Автор: wallstreet 3.7.2012, 13:55
Добрый день всем.
Господа, помогите разобраться с вопросами. В моем проекте объявление каждой котегории классов находится в своем .h файле, их реализация в .cpp файле, ну и в главном оконном приложении будут жить объекты этих классов. Так вот вопрос в том как лучше настроить взаимосвязь этих файлов  всех, как их грамотнее сообрать в кучу?

Ну во первых есть у меня ошибка которую не могу понять как решить.
Объявление класса в ConnDecl.h 
Код

#include "stdafx.h"
#include <Windows.h>
#include <WindowsX.h>
#include <Dde.h>
#include <Ddeml.h>

// класс управления соединением
class Connection
{
public:
    Connection();
    ~Connection();
    HCONV On(HINSTANCE hInst,LPCWSTR szService, LPCWSTR szTopic, LPCWSTR szItem);
    void Off();
    BOOL ConnectionStatus() const;
private:
    HWND hwnd;
    HINSTANCE hInst;
    HCONV hConv;
    FARPROC lpDdeProc;
    BOOL Status;
    DWORD idInst;
    HSZ hszService;
    HSZ hszTopic;
    HSZ hszItem;

};

реализация класса в ConnRealization.cpp:
Код

HDDEDATA EXPENTRY DDEClientCallback(WORD wType, WORD wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2);
HCONV Connection::On(HINSTANCE hInst, LPCWSTR szService, LPCWSTR szTopic, LPCWSTR szItem)
{
    Status = FALSE;
    hConv = NULL;

    //Создаем переходник для функции обратного вызова
    lpDdeProc = MakeProcInstance((FARPROC)DDEClientCallback, hInst);
    //Инициализируем DDEML
    if(DdeInitializeW((LPDWORD)&idInst, (PFNCALLBACK)lpDdeProc, APPCMD_CLIENTONLY, 0))
    {
        return NULL;
    }
    else
    {
        //при успешной инициализации создаем идентификаторы строк для сервиса,
        //раздела и элемента данных
        hszService = DdeCreateStringHandle(idInst, szService, CP_WINANSI);
        hszTopic = DdeCreateStringHandle(idInst, szTopic, CP_WINANSI);
        hszItem = DdeCreateStringHandle(idInst, szItem, CP_WINANSI);

        // Устанавливаем канал связи
        hConv = DdeConnect(idInst, hszService, hszTopic, (PCONVCONTEXT)NULL);
        if(hConv)
            Status = TRUE;
    }

    return hConv;
}

А вот и сама ошибка:
Цитата

Error    1    error LNK2019: unresolved external symbol "struct HDDEDATA__ * __stdcall DDEClientCallback(unsigned short,unsigned short,struct HCONV__ *,struct HSZ__ *,struct HSZ__ *,struct HDDEDATA__ *,unsigned long,unsigned long)" (?DDEClientCallback@@YGPAUHDDEDATA__@@GGPAUHCONV__@@PAUHSZ__@@1PAU1@KK@Z) referenced in function "public: struct HCONV__ * __thiscall Connection::On(struct HINSTANCE__ *,wchar_t const *,wchar_t const *,wchar_t const *)" (?On@Connection@@QAEPAUHCONV__@@PAUHINSTANCE__@@PB_W11@Z)    C:\Users\Андрей\Documents\Visual Studio 2010\Projects\R4T\R4T\ConnRealization.obj    R4T
Error    2    error LNK1120: 1 unresolved externals    C:\Users\Андрей\Documents\Visual Studio 2010\Projects\R4T\Debug\R4T.exe    R4T


Ну если судить по переводу с ангельского, то ругается компилятор на неразрешенный внешний символ. Могу предположить что компилятор  не может или не хочет найти такую функцию в dll откуда он экспортируется? Кстати в примере данная функция объявлялась как 
Код

HDDEDATA EXPENTRY _export DDEClientCallback(......)

но если я ее объявляю именно таким образом то выскакивает ошибка:
Цитата

    4    IntelliSense: explicit type is missing ('int' assumed)    c:\users\андрей\documents\visual studio 2010\projects\r4t\r4t\connrealization.cpp    10    27    R4T
Error    3    error C4430: missing type specifier - int assumed. Note: C++ does not support default-int    c:\users\андрей\documents\visual studio 2010\projects\r4t\r4t\connrealization.cpp    10    1    R4T
Error    1    error C2146: syntax error : missing ';' before identifier 'DDEClientCallback'    c:\users\андрей\documents\visual studio 2010\projects\r4t\r4t\connrealization.cpp    10    1    R4T

Так же заметил одну примечательную вещь, если описать реализацию не в .cpp а в .h где класс и объявлен, то все компилируется без проблем?!?!?!?!

Во вторых я еще не очень понимаю как лучше поступить с включением в файл реализации моих классов хедеры так, что бы они не повторялись. Тут мнения разошлись, мой учебник меня учит делать так:
Код

#ifndef CONNDECL_HPP
#define CONNDECL_HPP
    // текст моего хедера, кстати
    // не очень понятно с инклудами
    // или без
#endif

в то время как в нете все рекомендуют использовать
Код

#pragma once

хотя в примере используется 
Код

#pragma hdrstop

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

Автор: Cheloveck 3.7.2012, 15:52
По поводу ошибки линкера -- посмотри в своей документации библиотеку, в которой живёт эта функция и подключи её к проекту.


Цитата(wallstreet @  3.7.2012,  14:55 Найти цитируемый пост)
Во вторых я еще не очень понимаю как лучше поступить с включением в файл реализации моих классов хедеры так, что бы они не повторялись. Тут мнения разошлись, мой учебник меня учит делать так:
#ifndef CONNDECL_HPP
#define CONNDECL_HPP
    // текст моего хедера, кстати
    // не очень понятно с инклудами
    // или без
#endif

Это правильный, кроссплатформенный вариант


Цитата(wallstreet @  3.7.2012,  14:55 Найти цитируемый пост)
#pragma once

Это расширение компилятора Visual C++ и работает только с ним.
Цитата(wallstreet @  3.7.2012,  14:55 Найти цитируемый пост)
#pragma hdrstop

А это специфичная прагма Borland C++ Builder

Автор: wallstreet 3.7.2012, 17:32
Цитата(Cheloveck @  3.7.2012,  15:52 Найти цитируемый пост)
По поводу ошибки линкера -- посмотри в своей документации библиотеку, в которой живёт эта функция и подключи её к проекту.

Если не секрет где можно найти эту документацию? у меня visual studio 2010.
Поидее это же lib файл должен быть, так?

Автор: Cheloveck 3.7.2012, 19:39
wallstreet, я погуглил и понял, что MakeProcInstance принимает коллбек первым параметром, а значит ты сам должен реализовать эту функцию http://www.frontsys.com/DLL/dll00031.htm

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)