Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 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
ActiveX DLL из VB требуют регистрации


 так делай просто инсталлятор с программой и вставляй туда функцию копирования и регистрации компонента, у меня была такая проблема, очень помог мне:
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 <windows.h>
#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 - файле:

LIBRARY my_cool_dll
EXPORTS Message



Код в VB:

Declare Function Message Lib "my_cool_dll" (ByVal vbMessage As String) As String


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-сайт: sharpc.livejournal.com
 Профиль | | #13
Добавлено: 04.11.05 10:20
char _stdcall Message()
{
   char ret;
   ret = 'fuck';
   return (ret);
}
char *, иначе он вернет только первый символ

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам