Страница: 1 |
Страница: 1 |
Вопрос: Ищу пример работы с DLL
Добавлено: 03.11.05 07:45
Автор вопроса: astoro | ICQ: 649109
2 Hacker - Google я пытался использовать, но не нашел ничего понятного ;-)
В VC я - чайник.
Нужен простейший пример следующего содержания:
1. Проект DLL на Visual C++ 6.0, содержащий одну функцию:
функция принимает String параметр, и в зависимости от
его значения возвращает какое-нить String значение.
2. Проект на Visual Basic 6.0, подключающий эту DLL и
использующий эту функцию.
PS: Проект DLL нужен на C++, т.к. проекты ActiveX DLL из VB требуют регистрации, а это мне чрезвычайно неудобно. Нужно закинуть библитеку куче пользователей, не имеющих прав на регистрацию библиотек, а насколько я знаю, не ActiveX DLL не требуют регистрации.
Может у кто встречал такое?
Ответы
Всего ответов: 13
Номер ответа: 1
Автор ответа:
«UL.eXe»
ICQ: 197.895.916.247
Вопросов: 72
Ответов: 540
Профиль | | #1
Добавлено: 03.11.05 10:51
так делай просто инсталлятор с программой и вставляй туда функцию копирования и регистрации компонента, у меня была такая проблема, очень помог мне:
www.innosetup.com
Номер ответа: 2
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #2
Добавлено: 03.11.05 11:09
1. Создаешь на VC Win32 Dynamic-Link Library
2. Хряпаешь там свои функции с параметрами LPSTR как Extern C
3. В Def файле указываешь список импортируемых функций.
4. Компилишь.
Уж чего, а по этой теме в том же Google можно найти примеров - ну просто завались...
И не нужно так бояться COM. Не тот язык VB где можно без него обойтись
Номер ответа: 3
Автор ответа:
astoro
ICQ: 649109
Вопросов: 31
Ответов: 391
Профиль | | #3
Добавлено: 03.11.05 12:21
CPP:
#include "stdafx.h";
char _stdcall Message()
{
char ret;
ret = 'fuck';
return (ret);
}
DEF:
LIBRARY "MessageDLL"
DESCRIPTION 'MessageDLL Windows DLL'
EXPORTS
Message
Вариант 1
VB:
Private Declare Function Message Lib "chktrial.dll" () As String
Private Sub Command1_Click()
Print Message()
End Sub
Басик вылетает с неустранимой ошибкой (Память не может быть Read)
Вариант 2:
VB:
Private Declare Function Message Lib "chktrial.dll" () As Long
Private Sub Command1_Click()
Print Message()
End Sub
Выдает число (что правильно, и доказывает, что фукнция вызывается и фурчит что-то-там)
Номер ответа: 4
Автор ответа:
astoro
ICQ: 649109
Вопросов: 31
Ответов: 391
Профиль | | #4
Добавлено: 03.11.05 12:23
2 unknown lamer
Поздно уже инсталлятор делать, прога уже стоит у пользователей, нуно сделать обновление.
Номер ответа: 5
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #5
Добавлено: 03.11.05 12:55
нах такой неформализм? Передавай функции указатель на строку - LPSTR. Соотвественно, в параметрах вызова будет ByVal as String.
Номер ответа: 6
Автор ответа:
astoro
ICQ: 649109
Вопросов: 31
Ответов: 391
Профиль | | #6
Добавлено: 03.11.05 13:12
(( не понимаю
что за LPSTR
Номер ответа: 7
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #7
Добавлено: 03.11.05 13:51
Тип входного параметра - указатель на строку.
Создаешь в VB буффер, передаешь его как LPCSTR + длину. Как в АПИ.
Номер ответа: 8
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #8
Добавлено: 03.11.05 15:51
Зачем буфер? Делается без всяких буферов.
Полный код dll:
#include <stdlib.h>
#include <oleauto.h>
#pragma comment(lib, "kernel32.lib"
#pragma comment(lib, "user32.lib"
#pragma comment(lib, "oleaut32.lib"
#pragma comment(linker, "/ENTRY:main"
LPSTR ret_msg1 = "Message From DLL No 1";
LPSTR ret_msg2 = "Message From DLL No 2";
LPSTR swMessage1 = "this is the first message from vb";
LPSTR swMessage2 = "this is the second message from vb";
//===============================================================
LPSTR _stdcall Message(LPSTR vbMessage)
{
LPSTR retMessage;
MessageBox (NULL, vbMessage, NULL, NULL);
if (0==lstrcmp(vbMessage, swMessage1))
retMessage = (LPSTR) SysAllocString( (const OLECHAR*) ret_msg1 );
else if (0==lstrcmp(vbMessage, swMessage2))
retMessage = (LPSTR) SysAllocString( (const OLECHAR*) ret_msg2 );
else
retMessage = (LPSTR) SysAllocString( (const OLECHAR*) "no message found" );
return retMessage;
}
//===============================================================
BOOL WINAPI main(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason==DLL_PROCESS_ATTACH) return TRUE;
return FALSE;
}
В .def - файле:
EXPORTS Message
Код в VB:
Private Sub my_cool_button_Click()
Dim ret_message As String
ret_message = Message(ByVal "this is the first message from vb"
MsgBox ret_message
ret_message = Message(ByVal "this is the second message from vb"
MsgBox ret_message
ret_message = Message(ByVal "this is the third message from vb"
MsgBox ret_message
End Sub
И всё.
Номер ответа: 9
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #9
Добавлено: 03.11.05 16:13
Буффер - для аналогии с WinAPI. Просто хороший стиль и контроль ошибок по Return Value.
Номер ответа: 10
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #10
Добавлено: 03.11.05 16:27
Хм, если нам нужен хороший стиль, будем писать прогу на си. Кроме того, чтобы использовать буфер, надо знать максимальную длину возвращаемой строки, что не всегда возможно. Можно конечно специально отдельно вызвать процедуру для определения длины возвращаемой строки, чтобы узнать, какой размер буфера понадобится, но вот это как раз и есть нехороший стиль.
А так как мы юзаем VB, то сам M$ велел нам использовать родную vb-шную строку от SysAllocString. А если ошибка, то никто не мешает вернуть строку "no message found" (см. код), которую и будем расценивать как признак ошибки.
С целью уменьшения писанины можно процедуру Message в dll изменить так:
BSTR _stdcall Message(LPSTR vbMessage)
{
LPSTR retMessage;
MessageBox (NULL, vbMessage, NULL, NULL);
if  0==lstrcmp(vbMessage, swMessage1))
retMessage = ret_msg1;
else if (0==lstrcmp(vbMessage, swMessage2))
retMessage = ret_msg2;
else
retMessage = "error!!! no message found";
return SysAllocString( (const OLECHAR*) retMessage );
}
Банзай!
Номер ответа: 11
Автор ответа:
astoro
ICQ: 649109
Вопросов: 31
Ответов: 391
Профиль | | #11
Добавлено: 03.11.05 17:29
ИОПТА.
Две бутылки пива ушло, но вроде разобрался что к чему.
Т.е. в коде HOOLIGAN все ясно, все работает, - разобрался с тем, что мне нужно было. Задача решена, всем спасибо за помощь.
Видимо, переменные нужно было объявлять за функцией, - глобальные, или типа того.
Номер ответа: 12
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #12
Добавлено: 03.11.05 18:28
В vb возвращаются не глобальные переменные ret_msg1 или ret_msg2. Возвращается указатель на динамически выделенную при помощи SysAllocString строку, содержащую преобразованную в BSTR переменную ret_msg1.
Номер ответа: 13
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #13
Добавлено: 04.11.05 10:20
{
char ret;
ret = 'fuck';
return (ret);
}