Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как писать и работать с DLL???!!!

538
18 июля 2007 года
AVDEY
188 / / 17.11.2005
Вот появилась потребность написать DLL, что бы связать устройство, которое висит на com порте, с 1С.
Начал пробивать писать и не все почему то получается.
Вот моя тестовая DLL.(MYDLL.dll)
#include <windows.h>
_declspec (dllexport) void MY();

_declspec (dllexport) void MY()
{
MessageBox(NULL,"MYDLL","DFD",MB_OK);
}
///////////////////////////////////////////////////////////////////////////////////
А вот фрагмент кода программы которой хочу использовать DLL.
{
HMODULE h=LoadLibrary("MYDLL.dll");
if(h!=NULL)
{
FARPROC m=GetProcAddress(h,"MY");
if (m!=NULL)
{
}
else MessageBox("Error GetProcAddress");
FreeLibrary(h);
}
else
MessageBox("Error LoadLibrary");
}
Вобщем программа выдает "Error GetProcAddress" тоесть не может найти функцию.
В чем может быть причина? И как после получения адреса вызвать функцию которая описана в DLL?
538
18 июля 2007 года
AVDEY
188 / / 17.11.2005
Вот две неплохие ссылки которые нашел по DLL
http://lib.profi.net.ua/doc/prog/vcpp/visual/12.html
http://www.izone.kiev.ua/articles/cpp/205.htm
538
18 июля 2007 года
AVDEY
188 / / 17.11.2005
Вобщем разобрался почему не находило функцию.

DLL Должен быть таким:
#include <windows.h>

extern "C" _declspec(dllexport) void MY();


extern "C" _declspec (dllexport) void MY()
{
MessageBox(NULL,"MYDLL","DFD",MB_OK);
}

А фрагмент кода:
{
UpdateData(TRUE);

HINSTANCE hHin=NULL;

typedef void(WINAPI *MY_DLL)();
MY_DLL my_dll;
hHin=::LoadLibrary(m_EdAdressDll);
if(hHin!=NULL)
{
my_dll=(MY_DLL)::GetProcAddress(hHin,m_ED_NAME_FUNC);
/*Этим макросом, вместо второго параметра функции GetProcAddress, MAKEINTRESOURCE(1) можно вызвать функцию по индексу.*/
if(my_dll!=NULL)
{
(*my_dll)();
}
else MessageBox("Error GetProcAddress");
FreeLibrary(hHin);
}
else
MessageBox("Error Load DLL");
}

Но тему считаю что не нужно закрывать, так как можно обсудить нюансы написания библиотек, какие привелегии и недостатки использования DLL.
350
18 июля 2007 года
cheburator
589 / / 01.06.2006
extern "C" _declspec (dllexport) void MY();

К тому же, 1С прекрасно работает с OLE, поэтому имеет смысл переделать проект как OLE-сервер.
350
18 июля 2007 года
cheburator
589 / / 01.06.2006
Чёрт, меня опередили... )
350
18 июля 2007 года
cheburator
589 / / 01.06.2006
Обычно используют так называемое "статическое связывание". При компиляции DLL образуются два выходных файла - собственно, dll, и lib (библиотека импорта). Если эту lib подключить к проекту, в котором хотим использовать динамическую библиотеку, открывать ее с помощью LoadLibrary и искать адреса функций по именам или номерам не придется. К тому же, использование GetProcAddr не обладает безопасностью типов, в результате чего можно случайно или намеренно вызвать функцию не с теми параметрами или неверно интерпретировать ее возвращаемое значение, или вызвать с неверной конвенцией вызова.
В случае с подключением библиотеки с использованием .lib и .h таких проблем не наблюдается. Более того, как правило, и при написании dll, и при написании приложений с ее использованием как правило используется один и тот же заголовочный файл, что повышает удобство и безопасность.
Примерный код:
Файл "mydll.h":
 
Код:
#ifdef DLL
#define DLL_FUNCTION __declspec(dllexport)
#else
#define DLL_FUNCTION __declspec(dllimport)
#endif
DLL_FUNCTION int myfunc1(int);
extern "C" DLL_FUNCTION char *myfunc2 (double);

Файл "mydll.cpp":
 
Код:
#define DLL
#include "mydll.h"
// Реализация функций myfunc1 и myfunc2

Файл "myapp.cpp":
 
Код:
#include "mydll.h"
// Использование функций

В настройках проекта следует в разделе Configuration properties / Linker / Input / Additional dependencies добавить ссылку на файл .lib, полученный при компиляции библиотеки.
Будут работать, причем гарантированно правильно, обе функции - как видим, нет зависимости от extern "C".
538
19 июля 2007 года
AVDEY
188 / / 17.11.2005
На сколько я слыхал, спорить не буду, OLE-сервер было бы замечательно, но я никогда не работал с с ним, тем более не писал. И даже не представляю как это делать с помощью С++.
И ситуация получается такая. Я должен написать то что связывает устройство с 1С, хотя я сам с 1С никогда не работал. Настройка и написание приложений на 1С возлагается на другого человека. А мне надо написать что то вроде драйвера. Он сказал что ему максимально подходит DLL-ка. Хотя я думаю что OLE было бы не хуже.
350
19 июля 2007 года
cheburator
589 / / 01.06.2006
Если требуется драйвер торгового оборудования, лучше покопаться в инете, поскольку для большинства оборудования всё уже есть и прекрасно работает.
538
19 июля 2007 года
AVDEY
188 / / 17.11.2005
Я уже искал. Может слихали о проксимити картах и их считивателях. И драйверов к счытивателю нет. Производитель Вислал только протоколы, а дальше мол разбирайтесь сами.
Я чтото не очень могу разобратса в протоколе, может ктото сможет помочь?:

UART_option: 2400,8N1

your request: "MASTER_REQUEST"
#define MASTER_REQUEST ' ' //SPACE(0x20)

my answer(two vars):

first_var:
EMPTY_PACKET(card is absent): "CR"
#define CR 0x0D

second_var:
FULL_PACKET(card is present): "SYNCH,CARD_CODE[0,...,9],CS,CR"

#define SYNCH '#'


CARD_CODE and CS: '0','1',...,'9','A',...,'F'
=> ('0'<=CARD_CODE/CS<='9')||('A'<=CARD_CODE/CS<='F') - may be alt_verification_rull

if('0'<=CARD_CODE<='9') real_card_code=CARD_CODE-48;
if('A'<=CARD_CODE<='F') real_card_code=CARD_CODE-55;

real_check_sum=real_card_code[0]^real_card_code[1]...^real_card_code...^real_card_code[9]
CS=real_check_sum+ 48 or 55;


- only four LSB is card_code_bits

card_code_format in your Data_Base:

CC[0]=(relal_card_code[0]<<4)|relal_card_code[1])
CC[1]=(relal_card_code[2]<<4)|relal_card_code[3])
CC[2]=(relal_card_code[4]<<4)|relal_card_code[5])
CC[3]=(relal_card_code[6]<<4)|relal_card_code[7])
CC[4]=(relal_card_code[8]<<4)|relal_card_code[9])

Example:

full_packet: '#','0','A','B','C','2','6','0','1','0','4','C',0x0D

real_card_code[0]='0'-48=0x00;
real_card_code[1]='A'-55=0x0A;
real_card_code[2]='B'-55=0x0B;
real_card_code[3]='C'-55=0x0C;
real_card_code[4]='2'-48=0x02;
real_card_code[5]='6'-48=0x06;
real_card_code[6]='0'-48=0x00;
real_card_code[7]='1'-48=0x01;
real_card_code[8]='0'-48=0x00;
real_card_code[9]='4'-48=0x04;

real_check_sum=0x00^0x0A^0x0B^0x0C^0x02^0x06^0x00^0x01^0x00^0x04=0x0C
real_check_sum>9 => CS=real_check_sum+55=0x0C+55='C'

hex: bin:
CC[0]=0x0A 0000 1010
CC[1]=0xBC 1011 1100
CC[2]=0x26 0010 0110
CC[3]=0x01 0000 0001
CC[4]=0x04 0000 0100

in practic useful only CC[2](family_code) and CC[3,4](member_code) =>

save_formats:
hex: decimal:
0x26,0x01,0x04 38,1,4
0x26,0x0104 38,260
0x260104 2490628

Вобщем так, то что я понял ето то что устройство работает на скорости 2400 бод/с 8 бит данних и 1 стоп бит.
Далее идет функция опроса считивателя с двумя переменними, така как я понял. Первая очищает буфер тоесть надо подать "CR"
А потом сам запрос начиная с '#',CARD_CODE[0,...9],CS,CR;
Не могу понять что надо передать в CARD_CODE[0,...9] и что за переменная CS ели она нигде не обявленная. в отличии #define CR 0x0D
538
20 июля 2007 года
AVDEY
188 / / 17.11.2005
Вобщем возвращаемся к DLL.
Код:
{
UpdateData(TRUE);

HINSTANCE hHin=NULL;

typedef void(WINAPI *MY_DLL)();
MY_DLL my_dll;
hHin=::LoadLibrary(m_EdAdressDll);
if(hHin!=NULL)
{
my_dll=(MY_DLL)::GetProcAddress(hHin,m_ED_NAME_FUN C);
/*Этим макросом, вместо второго параметра функции GetProcAddress, MAKEINTRESOURCE(1) можно вызвать функцию по индексу.*/
if(my_dll!=NULL)
{
(*my_dll)();
}
else MessageBox("Error GetProcAddress");
FreeLibrary(hHin);
}
else
MessageBox("Error Load DLL");
}

В этом фрагменте кода мне не удавалось запустить функцию с DLL с параметрами. Программа выдавала ошибку и закрывалась.

А вот так работает
Код:
{
    HINSTANCE hHin=NULL;

    typedef DWORD(*InitComPort)(UINT nPort);

    InitComPort m_InitComPort=0;
hHin=::LoadLibrary(m_EdAdressDll);
if(hHin!=NULL)
{
   
    m_InitComPort=(InitComPort)::GetProcAddress(hHin,"InitComPort");

    if(m_InitComPort!=NULL)
    {
       
        DWORD retur=m_InitComPort(1);
    if(retur!=0)MessageBox("ERROR OPEN PORT RETURN");
    }
    else MessageBox("Error GetProcAddress");
       
}
else
MessageBox("Error Load DLL");
}

И фрагмент DLL
 
Код:
_declspec (dllexport) DWORD InitComPort(UINT nPort)
{
return 0;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог