#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);
Как писать и работать с DLL???!!!
Начал пробивать писать и не все почему то получается.
Вот моя тестовая 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?
Вот две неплохие ссылки которые нашел по DLL
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.
К тому же, 1С прекрасно работает с OLE, поэтому имеет смысл переделать проект как OLE-сервер.
Чёрт, меня опередили... )
В случае с подключением библиотеки с использованием .lib и .h таких проблем не наблюдается. Более того, как правило, и при написании dll, и при написании приложений с ее использованием как правило используется один и тот же заголовочный файл, что повышает удобство и безопасность.
Примерный код:
Файл "mydll.h":
Код:
Файл "mydll.cpp":
Код:
#define DLL
#include "mydll.h"
// Реализация функций myfunc1 и myfunc2
#include "mydll.h"
// Реализация функций myfunc1 и myfunc2
Файл "myapp.cpp":
Код:
#include "mydll.h"
// Использование функций
// Использование функций
В настройках проекта следует в разделе Configuration properties / Linker / Input / Additional dependencies добавить ссылку на файл .lib, полученный при компиляции библиотеки.
Будут работать, причем гарантированно правильно, обе функции - как видим, нет зависимости от extern "C".
И ситуация получается такая. Я должен написать то что связывает устройство с 1С, хотя я сам с 1С никогда не работал. Настройка и написание приложений на 1С возлагается на другого человека. А мне надо написать что то вроде драйвера. Он сказал что ему максимально подходит DLL-ка. Хотя я думаю что OLE было бы не хуже.
Если требуется драйвер торгового оборудования, лучше покопаться в инете, поскольку для большинства оборудования всё уже есть и прекрасно работает.
Я чтото не очень могу разобратса в протоколе, может ктото сможет помочь?:
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
Код:
{
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");
}
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");
}
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;
}
{
return 0;
}