Visual Basic, .NET, ASP, VBScript
 

   
   
     

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

Страница: 1 | 2 |

 

  Вопрос: Пишем и пользуем DLL на CPP Добавлено: 03.02.04 23:02  

Автор вопроса:  Rebel | Web-сайт: rebel.bos.ru

пишу я тут dll на С++, которую потом нада использовать в VB

получилось сделать так, что VB видит функции, а вот так чтоб они работали - хрен :(

вопрос в том что я не так делаю?? вот что есть:

DLL'овский h-файл:

extern "C" {

RELIB_API void About(HWND hWnd);

RELIB_API LPSTR RuDate(LPSTR EnDate);

}

DLL'овский CPP-файл:

#include "ReLib.h"

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

break;

}

return TRUE;

}

RELIB_API void About(HWND hWnd)

{

MessageBox(hWnd,"Copyright (c)1995-2004 by Rebel™ http://rebel.bos.ru","About ReLib",MB_OK|MB_ICONINFORMATION);

}

RELIB_API LPSTR RuDate(LPSTR EnDate)

{

if(strlen(EnDate) < 10) return "";

LPSTR ret = new char[10];

ret[0] = EnDate[3];

ret[1] = EnDate[4];

return ret;

}

билдится без проблем.

VB'шная форма:

Private Declare Sub About Lib "ReLib.dll" (ByVal hwnd As Long)

Private Declare Function rudate Lib "ReLib.dll" Alias "RuDate" (ByVal EnDate As String) As String

Private Sub Form_Load()

About Me.hwnd

MsgBox rudate(Date$)

End Sub

при запуске выводит мессадж бокс но потом пишет: кугт-time error 49:Bad DLL calling conversion

при запуске второй функции - пишет тоже самое тока стразу

вопрос адресован в принципе к тем кто ето уже делал.. заранее спасибо всем откликнувшимся :)

Ответить

  Ответы Всего ответов: 24  

Номер ответа: 1
Автор ответа:
 Rebel



Вопросов: 32
Ответов: 50
 Web-сайт: rebel.bos.ru
 Профиль | | #1
Добавлено: 04.02.04 00:06

чуть не забыл в h-файле еще прописано:

#define RELIB_API __declspec(dllexport)

Ответить

Номер ответа: 2
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #2
Добавлено: 04.02.04 02:19

DLL-ки лучше писать на Power Basic.

По нему даже форум есть.

Ответить

Номер ответа: 3
Автор ответа:
 USA



Вопросов: 1
Ответов: 184
 Профиль | | #3 Добавлено: 04.02.04 03:42

Где-то надо прописать stdcall. Вот похожий вопрос их сишной рассылки:

 Вопрос № 1406

Как сделать чтоб экспорное имя функции совпадало с настоящим (Visual C++)
Объявляю
extern "C" __declspec(dllexport) void __stdcall Destroy_MainDll(void)
Получаю в модуле Dll
_Destroy_MainDll@0
А как получить
Destroy_MainDll
Функция должна вызываться не только в C++



Вопрос отправлен: 21.01.2004, 21:04
Отправитель: Алексей (aleksey_@pisem.net)

[Следующий вопрос >>] [Список вопросов]



Отвечает vitya

Добрый день, Алексей!
Напиши def файл.


Ответ отправлен: 22.01.2004, 09:56
Отправитель: vitya

 

По собственному опыту: личше писать DLL на ASM. Это самый простой язык.

Ответить

Номер ответа: 4
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #4
Добавлено: 04.02.04 05:39

На PB вообще просто.

Function ИмяФункции Alias "Имя в Таблице экспорта" (Параметры) EXPORT As Тип

End Function

Ответить

Номер ответа: 5
Автор ответа:
 Artificial Intelligence



ICQ: 275368971 

Вопросов: 8
Ответов: 131
 Профиль | | #5 Добавлено: 04.02.04 10:30

В h-файле пишешь:

 

#define RELIB_API extern "C" __declspec(dllexport)

RELIB_API void WINAPI About (HWND hWnd);

 

Где WINAPI определен в windef.h как #define WINAPI __stdcall ,

т.е. можно написать extern "C" __declspec(dllexport) void __stdcall About (HWND hWnd);

как собственно и написал USA.

 

В cpp-файле пишешь:

 

#include "h-файл"

 

void WINAPI About (HWND hWnd)   или void __stdcall About (HWND hWnd);

{

         ...

}

Ответить

Номер ответа: 6
Автор ответа:
 Rebel



Вопросов: 32
Ответов: 50
 Web-сайт: rebel.bos.ru
 Профиль | | #6
Добавлено: 04.02.04 19:08

НИФИГА!!! :((((((((((((

если писать с __stdcall aka WINAPI aka APIENTRY, то вб выдает ошибку: Cant find DLL entry point for About :( т.е. я так понял что функция становится не экспортной :(

в общем ето не пашет :( нада че-то еще придумывать...

на всяк случай пишу DLL на Visual C++ 6.0, можт у него есть какие-то характерные особенности???

Ответить

Номер ответа: 7
Автор ответа:
 Artificial Intelligence



ICQ: 275368971 

Вопросов: 8
Ответов: 131
 Профиль | | #7 Добавлено: 04.02.04 19:37

Ну Cant find DLL entry point это лучше чем Bad DLL calling conversion, мне так кацца.

 

Теперь надо покопаться в свойствах проекта и поставить:

Conficuration Type - Dynamic Library (.dll)

Use of MFC - Use Standard Windows Libraries

Use of ATL - Not Using ATL

 

Ну и Relase наверно надо делать.

 

Может еще чего то.., если не заработает попробую уточнить, была помница такая проблема.

Ответить

Номер ответа: 8
Автор ответа:
 Artificial Intelligence



ICQ: 275368971 

Вопросов: 8
Ответов: 131
 Профиль | | #8 Добавлено: 04.02.04 20:17

Прости стормозил, если ты в VC6 пишешь,

то при создании проекта выбираешь Win32 ;Dynamic-Link Library

Ответить

Номер ответа: 9
Автор ответа:
 Rebel



Вопросов: 32
Ответов: 50
 Web-сайт: rebel.bos.ru
 Профиль | | #9
Добавлено: 04.02.04 20:25

все так, билд релиза не помог.... все рано не может найти точку входа :(

Ответить

Номер ответа: 10
Автор ответа:
 Chill



ICQ: 554200 

Вопросов: 101
Ответов: 343
 Профиль | | #10 Добавлено: 05.02.04 00:20

to Rebel: Ты пишешь dll на Си, а не на Си++ =)

to USA: "Где-то надо прописать stdcall" - не надо, т.к. WINAPI и есть переопределенный __stdcall, т.е. typedef WINAPI __stdcall;

Можешь писать WINAPI, а можешь __stdcall - это одно и то же.

to CyRax: конечно лудше их писать на PowerBasic, си\си++ вообще [sensored], и винды глючат только из-за того, что все dll и api, содержащиеся в dll, были написаны на Си... Были бы на написаны на PowerBasic'е ничего бы не глючило...

Вообщем так, теперь по делу...

Я написал dll, протестил ее в Си - все работает, все функции из dll выполняютя.

Попрбовал в vb неявную загрузу:

Private Declare Sub About Lib "E:\Работы\C_C++\_DLL\ForVbNetRu\VB_test\ForVbNetRu.dll" (ByVal hwnd As Long)

'Private Declare Function rudate Lib "E:\Работы\C_C++\_DLL\ForVbNetRu\VB_test\ForVbNetRu.dll" Alias "RuDate" (ByVal EnDate As String) As String

Вот код DllMain из dll:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)

{

switch (fdwReason)

{

case DLL_PROCESS_ATTACH:

MessageBox(NULL,"Enter to the Dll","Relib",MB_OK);

break;

case DLL_PROCESS_DETACH:

MessageBox(NULL,"Enter of Dll","Relib",MB_OK);

break;

}

return TRUE;

}

И смотрю что писходит...

При запуске приложения на VB выскакивает сообщение "Enter to the Dll", потом тутже

"Enter of Dll", а уже потом возникает ошибка "Не могу найти точку входа"...

ИМХО тут происходит следющее:

Наш процесс присоединяется к dll, потом отсоединяется от нее и уже только после этого пытается загрузить функцию из dll... вот и возникает ошибка...

Как это исправить пока не знаю, если что-то получится - напишу...

Возможено все будет работать, если использовать LoadLibrary/FreeLibrary...

Надеюсь, кому-то написанное интересно...

=====================================================================

С уважением

Chill.

Ответить

Номер ответа: 11
Автор ответа:
 Chill



ICQ: 554200 

Вопросов: 101
Ответов: 343
 Профиль | | #11 Добавлено: 05.02.04 02:09

Вот дока, я ее не читал...

http://www.statsoft.ru/home/portal/applications/svb_adviser/externaldlls.htm

Ответить

Номер ответа: 12
Автор ответа:
 Artificial Intelligence



ICQ: 275368971 

Вопросов: 8
Ответов: 131
 Профиль | | #12 Добавлено: 05.02.04 12:01

Чегото с этим Win32 ;Dynamic-Link Library геморой какойто получается.

Вот попробуй подругому:

Создаешь проект - MFC AppWizard(dll)

What type of DLL ... - Regular DLL with MFC statically linked

     Ну етот Wizard создаст кучу всяких файлов, эти файлы трогать не надо

 Создаешь один h-файл и один cpp-файл, с одинаковым именем

В h-файле  пишешь

__declspec(dllexport) void _stdcall About (HWND hWnd);

__declspec(dllexport) LPSTR _stdcall RuDate (LPSTR EnDate);

В cpp-файле пишешь

#include "stdafx.h"

#include "Файл.h"

__declspec(dllexport) void _stdcall About (HWND hWnd)

{

MessageBox(hWnd,"Copyright (c)1995-2004 by Rebel™ http://rebel.bos.ru","About ReLib",MB_OK|MB_ICONINFORMATION);

}

__declspec(dllexport) LPSTR _stdcall RuDate (LPSTR EnDate)

{

if (strlen (EnDate) < 10) return "";

LPSTR ret = new char[10];

ret[0] = EnDate[3];

ret[1] = EnDate[4];

return ret;

}

Теперь находишь def-файл, находишь строчку EXPORTS и делаешь так:

EXPORTS

; Explicit exports can go here

About @1

RuDate @2

Теперь компилируеш всю эту ботву, и типа все готово.

Declare Sub About Lib "Имя.dll" (ByVal abc As Long)

Declare Function RuDate Lib "Имя.dll" (ByVal abc As String) As String

Ответить

Номер ответа: 13
Автор ответа:
 Chill



ICQ: 554200 

Вопросов: 101
Ответов: 343
 Профиль | | #13 Добавлено: 05.02.04 12:55

Как вы думаете, народ... здесь у вас память не течет?

LPSTR ret = new char[10];

Отвечу - течет...

после вызова new , при завершении работы с выделенным участком памяти в си++ надо делать delete(освобождения участка памяти после его использования)...

А-то у вас происходит утечка памяти, в C# это прокатит, т.к. "сборщик мусора" все подчистит, а в си++ увы...

Почему бы просто не сделать char ret[10];?

to Rebel: прошу прощения, ты всетаки используешь си++, т.к. оператора new в си нету =) А остальной код у тя СИшный...

Еще я не уверен, что dll, написанную с использованием MFC можно юзать из других языков программирования...

Ответить

Номер ответа: 14
Автор ответа:
 Artificial Intelligence



ICQ: 275368971 

Вопросов: 8
Ответов: 131
 Профиль | | #14 Добавлено: 05.02.04 13:15
2 Chill На счет работоспособности DLL'ки написаной по способу выше(Номер ответа: 12), могу зказать: я её из VB тока что юзал, все работало, правда размер её большой чего то получается, даже если убрать отладочную инормацию.

Ответить

Номер ответа: 15
Автор ответа:
 Chill



ICQ: 554200 

Вопросов: 101
Ответов: 343
 Профиль | | #15 Добавлено: 05.02.04 13:41

to Artificial Intelligence: MFC чего ты хочешь =) Размер будет большим.

Вообщем у меня получилось сделать dll с нуля и поюзать ее в vb, сейчас делаю dll как у Relib'а, как сделаю - выложу и объясню в чем фишка =)

Ответить

Страница: 1 | 2 |

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



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