fly
Гость
|
|
« : 31-07-2008 02:55 » |
|
Я хочу написать DLL-ку, которая содержит функцию. Эта функция, в вызывающем приложении, должна принять параметры и сделать с ними работу. Вот такая проблема: DLL.cpp:#include <windows.h> #include <SysUtils.hpp> #pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } //---------------------------------------------------------------------------
extern "C" char * _declspec(dllexport) MyMess(char *a, char *b, int i, int j, int pass, long int counter, int trash);
char *MyMess(char *a, char *b, int i, int j, int pass, long int counter, int trash) { for(int pass=0; pass<counter; pass++)//сортировка пузырек for(int i=0; i<counter-1; i++) { if(a[i] > a[i+1]) { trash=a[i]; a[i]=a[i+1]; a[i+1]=trash; } }
return 0; } Unit1.h:public: // User declarations HINSTANCE dllH; typedef char(_import * FuncType (char, char, int, int, int, long int, int)); FuncType * funcH; Вызывающее приложение Unit1.cpp:void __fastcall TForm1::Button1Click(TObject *Sender) { //char a[4096]; char * a = new char[4096]; //char b[12288]; char * b = new char[12288];
int pass = 0; int i = 0; int j = 0; long int counter = 0; int trash=0;
dllH = LoadLibrary("Project1.dll");//загрузить библиотеку("путь") if (dllH) { funcH = (FuncType*)GetProcAddress(dllH,"MyMess");//получение доступа к ф-ии //ShowMessage("Грузанули!"); } else ShowMessage("Не удалося!");
funcH(*a, *b, i, j, pass, counter, trash);//вот сдесь компл. указывает на ошибку
FreeLibrary(dllH); //после работы с dll необходимо освобождать память
ShowMessage(a); } Вызывающее приложение компилируется. При вызове (*.exe), исполняется. Если нажать на кнопку Button1, появляется сообщение: Projrct Project2.exe raised exeption classs EAccessViolation with message 'Access violation at address 00000000. Read of address 00000000'. Process stoped. Use Step or run to continue.В чем может быть проблема? Можно в DLL-ке, просто, обозначить встраиваемую функцию, которая содержит код, который нужно просто подставить и все? Если можно, как это сделать?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Online
Сообщений: 13
|
|
« Ответ #1 : 31-07-2008 03:25 » |
|
у тебя функция описана как extern "C" ..... char * MyMess(char *a, char *b,....);
тип функции определяешь совсем другой: typedef char (_import * FuncType (char, char, int, int, int, long int, int)); //надо : //typedef char* (_import * FuncType (char*, char*, int, int, int, long int, int));
и передаёшь не правильно: char * a ; char * b ; funcH(*a, *b, i, j, pass, counter, trash); //надо //funcH(a, b, i, j, pass, counter, trash);
это чисто синтаксис
|
|
|
Записан
|
|
|
|
fly
Гость
|
|
« Ответ #2 : 31-07-2008 06:42 » |
|
Изменил. Раскоментировал строку ShowMessage("Грузанули!"); При вызове *.exe модуля, появляется сообщение "Грузанули!". Это значит, загруз DLL-ки произошел. Нажимаю "Ок". Появляется ошибка: Access violation at address 00000000. Read of address 00000000То есть, другими словами, я не правильно вызываю ф-ию из DLL. Что это может быть? Я всю ночь с этим сидел. Просто кошмар.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Online
Сообщений: 13
|
|
« Ответ #3 : 31-07-2008 06:50 » |
|
изменил
покажи ) неправильно ты , скорее всего, указатель передаёшь, и программа пытается читать по нулевому адресу
|
|
|
Записан
|
|
|
|
fly
Гость
|
|
« Ответ #4 : 31-07-2008 07:06 » |
|
То есть мне нужно чтоб сортировка массива, который объявлен в вызывающем приложении, была осуществлена из функции DLL, после сортировки в дело вступает код, расположенный ниже вызова ф-ии (я не стал его вставлять, не суть важно) #include <SysUtils.hpp> #pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } //---------------------------------------------------------------------------
extern "C" char * _declspec(dllexport) MyMess(char *a, char *b, int i, int j, int pass, long int counter, int trash);
char *MyMess(char *a, char *b, int i, int j, int pass, long int counter, int trash) { for(int pass=0; pass<counter; pass++)//сортировка пузырек for(int i=0; i<counter-1; i++) { if(a[i] > a[i+1]) { trash=a[i]; a[i]=a[i+1]; a[i+1]=trash; } }
return 0; } public: // User declarations __fastcall TForm1(TComponent* Owner); HINSTANCE dllH; //typedef char(_import * FuncType (char, char, int, int, int, long int, int)); typedef char* (_import * FuncType (char*, char*, int, int, int, long int, int)); FuncType * funcH; dllH = LoadLibrary("Project1.dll");//загрузить библиотеку("путь") if (dllH) { funcH = (FuncType*)GetProcAddress(dllH,"MyMess");//получение доступа к ф-ии ShowMessage("Грузанули!"); } else ShowMessage("Не удалося!");
funcH(a, b, i, j, pass, counter, trash);
FreeLibrary(dllH); //после работы с dll необходимо освобождать память
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Online
Сообщений: 13
|
|
« Ответ #5 : 31-07-2008 07:37 » |
|
ага, ещё косяк:
1) FuncType * funcH; надо FuncType funcH;
2) funcH = (FuncType*)GetProcAddress(dllH,"MyMess");//получение доступа к ф-ии
надо
funcH = (FuncType)GetProcAddress(dllH,"MyMess");//получение доступа к ф-ии
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Online
Сообщений: 13
|
|
« Ответ #6 : 31-07-2008 07:41 » |
|
если это не поможет, то перед строкой funcH(a, b, i, j, pass, counter, trash); яви на экран значения a, b,
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #7 : 31-07-2008 08:06 » |
|
fly, можешь выложить полученную длл? Явно только что GetProcAddress возвращает нулевой указатель.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
fly
Гость
|
|
« Ответ #8 : 31-07-2008 23:47 » |
|
Все получилось! Ошибка была в том, что нужно было поставить знак "_" перед вызовом ф-ии: funcH = (FuncType*)GetProcAddress(dllH,"_MyMessUp"); Потому, что при __stdcall передача параметров осуществляется так, что не идет проверка на количество передаваемых параметров и их типы, а так же порядок.
|
|
|
Записан
|
|
|
|
fly
Гость
|
|
« Ответ #9 : 31-07-2008 23:48 » |
|
Вторая часть:
|
|
|
Записан
|
|
|
|
fly
Гость
|
|
« Ответ #10 : 01-08-2008 00:37 » |
|
Допустим, мне надо включить в DLL-ку какую-то часть работы со стандартными компонентами. В DLL, это как реализовать? Специальные заголовочные ф-лы нужно использовать?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Online
Сообщений: 13
|
|
« Ответ #11 : 01-08-2008 05:04 » |
|
Ошибка была в том, что нужно было поставить знак "_" перед вызовом ф-ии:
при чём тут это, может просто имя у функции такое было ? )
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #12 : 01-08-2008 05:28 » |
|
Underscore character (_) is prefixed to names, except when exporting __cdecl functions that use C linkage.
оно?
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #13 : 01-08-2008 06:45 » |
|
Народ, не забываем, что речь идет о Borland, а там реально надо эти черточки ставить (сам на Борланде никогда не писал, а вот использовать dll написанные на Борланд приходилось), помоему их компилятор сам для экспортируемых функций проставляет (или что-то в этом роде), для чего - не спрашивайте - не знаю
|
|
|
Записан
|
С уважением Lapulya
|
|
|
fly
Гость
|
|
« Ответ #14 : 01-08-2008 06:58 » |
|
Вад, да оно. Алексей1153++, имя ф-ии было без "_" Это кто-то делал(?): Допустим, мне надо включить в DLL-ку какую-то часть работы со стандартными компонентами. В DLL, это как реализовать? Специальные заголовочные ф-лы нужно использовать?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #15 : 01-08-2008 07:04 » |
|
fly, насчет последнего: поройся в этом разделе в недавних темах - было уже. Можно выносить часть проекта в dll. В том числе и GUI.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|