Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.02.2013, 02:08   #1
Dark Illusion
Пользователь
 
Регистрация: 28.03.2012
Сообщений: 15
По умолчанию Работа с DLL библиотеками

Здравствуйте. Помогите, пожалуйста, переделать программу.
Определите следующие функции для работы с массивом:
1) int GetValue(Pairs* p, char* name, int* var); // получить значение для заданного имени (функция должна возвратить 0 если нет такого имени и 1 в случае успеха, а значение возвращать через второй параметр функции);
2) void SetValue(Pairs* p, char* name, int value); // установить значение для заданного имени (если такого имени в массиве нет, то добавить в массив новую пару);
3) void PrintPairs(Pairs* p); – вывод всех пар на экран.

Код:
#include <iostream>
#include <cstring>
#include <windows.h> 
struct Pair
{
    char* name; //имя
    int value;  //значение
};
 
#define MAX_PAIRS 100
 
struct Pairs
{
    Pair items[MAX_PAIRS];  //массив пар
    int count;              //количество пар в массиве
};
 
// создаёт в куче копию строки src и возвращает на неё указатель 
char* StrDup(const char* src)
{
    char* dest = new char[std::strlen(src) + 1];
    return std::strcpy(dest, src);
}
 
int GetValue(const Pairs *p, const char *name, int *var)
{ 
    for (int i = 0; i < p->count; i++)
    {
        // сравниваем строки с помощью функции strcmp(если она возвращает 0, то строки равны)
        if(std::strcmp(p->items[i].name, name) == 0)
        {
            // помещаем найденное значение в переменную адрес которой хранит переменная var
            *var = p->items[i].value; 
            
            // найдено
            return 1; 
        }
    }
    
    return 0; // не найдено
}
 
void SetValue(Pairs* p, const char* name, int value) 
{       
    for (int i = 0; i < p->count; i++)
    {
        // сравниваем строки с помощью функции strcmp(если она возвращает 0, то строки равны)
        // условие вида if(p->items[i].name == name) сравнит указатели(адреса), а не строки
        if (std::strcmp(p->items[i].name, name) == 0)
        {
            p->items[i].value = value; 
            return; // и никаких flag'ов
        }        
    }
    
    p->items[p->count].name = StrDup(name);
    p->items[p->count].value = value;
    p->count++;
}
 
void PrintPairs(const Pairs *p) 
{
    for (int i = 0; i < p->count; i++)
    {
        std::cout << p->items[i].name << " -> ";
        std::cout << p->items[i].value << "\n";
    }
}
 
void Init(Pairs *p)
{
    p->count = 0;
}
 
void Free(Pairs *p)
{
    for (int i = 0; i < p->count; i++)
        delete[] p->items[i].name;
}
 
int main ()
{
    Pairs d;
    Init(&d);
        
    SetValue(&d, "lolooo", 25);            
    SetValue(&d, "lol" , 40);    
    
    PrintPairs(&d);
    
    //-----
    
    int value;
    
    if(GetValue(&d, "lol", &value) == 0)    
        std::cout << "not found\n";        
    else    
        std::cout << value << "\n";    
    
    //-----
    
    SetValue(&d, "lol" , 10);        
    PrintPairs(&d);    
    
    Free(&d);
system("pause");
    return 0;
}
1) Функции, описанные выше, нужно оформить в виде библиотеки DLL;
2) Создать новый проект для демонстрации работы с DLL и функциями;
3) В первом варианте программы необходимо использовать динамическое связывание без импорта, во втором – статическое связывание с импортом;
4) при динамическом связывании необходимо в проекте с главной программой объявить указатели на функции, содержащиеся в DLL (см. пример решения ниже);
4) при статическом связывании необходимо создать специальный заголовочный файл с объявлениями функций (см. пример решения ниже);

Примеры решения:
1) Динамическое связывание:

Файл MyDate.cpp
Код:
struct Date {
    //...
};
__declspec(dllexport) void GetDate(Date * d)
{
    //...
}
//...
Текст основной программы
Код:
struct Date {
    //...
}
typedef void(__cdecl * PFGETDATE)(Date *);
//...
typedef void (__cdecl * PFWRITEDATE)(char *, Date *, int);
//...
void main()
{
    HANDLE hLibrary;
    PFGETDATE pfGetDate;
    //...
    Date dt;
    hLibrary = LoadLibrary("MyDate.dll");
    if (!hLibrary) return;
    pfGetDate = 
        (PFGETDATE)GetProcAddress(hLibrary,"GetDate");
    if (pfGetDate) pfGetDate(&dt);
 
    //...
    FreeLibrary(hLibrary);
}
2) Статическое связывание:

Заголовочный файл MyTime.h
Код:
#ifndef MYLIBAPI
    #define MYLIBAPI __declspec(dllimport)
#endif
 
MYLIBAPI struct Time
{
    //...
};
MYLIBAPI void GetTime(Time *);
//...
void WriteTime(char *, Time *, int);
//...
 
Файл MyTime.cpp
 
#define MYLIBAPI    __declspec(dllexport)
#include "MyTime.h"
 
MYLIBAPI void GetTime(Time * t)
{
    //...
}
//...
Текст основной программы
Код:
//укзание компоновщику, что при компоновке необходимо использовать MyTime.lib
#pragma comment(linker, "MyTime.lib")
 
#include "MyTime.h"
 
void main()
{
    Time t;
    GetTime(&t);
    //...
}
Помогите, пожалуйста, переделать программу, функции я описал, а с библиотеками ничего не получается. Заранее спасибо.

Последний раз редактировалось Dark Illusion; 22.02.2013 в 02:14.
Dark Illusion вне форума Ответить с цитированием
Старый 25.02.2013, 08:24   #2
bambarbia
Пользователь
 
Регистрация: 20.10.2011
Сообщений: 44
По умолчанию

все связывается 2 проекта делаешь в одном оин для .dll, другой для екзешника, инклюдишь в запускающий .h Dllки , только надо, чтоб .dll при компиляции образовался с екзешником в одной папке, в свойствах проекта -> debug -> workspace->и указываешь где .dll у тебя скомпилировалась.
Код:
__declspec(dllexport) void GetDate(Date * d)//...названия функций и типы твои
{
   / /...
}
этот код должен быть в заголовочном файле .h Dllки
когда скомпилируешь dll и будишь писать вызывающую программу (это код из твоей функции main) при вызове этих функций не будет появляться ошибок кода

да, забыл при динамическом связывании еще надо добавить Reference в свойствах проекта , когда dll уже есть в том же проекте, для запускающей программы делаешь на нее ссылку (add reference) там вторая строчка в окне нажми и е сли визуалстудия то она ее сама увидит. Все.

Последний раз редактировалось bambarbia; 25.02.2013 в 08:34.
bambarbia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
работа с Библиотеками windows в C# D][mon C# (си шарп) 1 02.06.2012 14:34
работа с библиотеками dll(delphi) Hitory Помощь студентам 0 10.03.2012 13:35
Стандартные средства для работы с динамическими библиотеками(dll,so) Пепел Феникса Общие вопросы C/C++ 3 20.08.2011 13:11
Работа с dll библиотеками в С# kloffelin Помощь студентам 6 27.09.2010 23:14
работа с библиотеками kuzmich Общие вопросы Delphi 2 25.02.2009 19:39