Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: DLL не работает как надо  (Прочитано 10564 раз)
0 Пользователей и 1 Гость смотрят эту тему.
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-ке, просто, обозначить встраиваемую функцию, которая содержит код, который нужно просто подставить и все? Если можно, как это сделать?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #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.
Что это может быть?
Я всю ночь с этим сидел. Просто кошмар.

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #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 необходимо освобождать память
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #5 : 31-07-2008 07:37 » 

ага, ещё косяк:

1)
FuncType * funcH;
надо
FuncType funcH;

2)
funcH = (FuncType*)GetProcAddress(dllH,"MyMess");//получение доступа к ф-ии

надо

funcH = (FuncType)GetProcAddress(dllH,"MyMess");//получение доступа к ф-ии
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #6 : 31-07-2008 07:41 » 

если это не поможет, то перед строкой
funcH(a, b, i, j, pass, counter, trash);
яви на экран значения
a,
b,
Записан

Джон
просто
Администратор

de
Offline 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 передача параметров осуществляется так, что не идет проверка на количество передаваемых параметров и их типы, а так же порядок.

* Ok2.part1.rar (250 Кб - загружено 725 раз.)
Записан
fly
Гость
« Ответ #9 : 31-07-2008 23:48 » 

Вторая часть:

* Ok2.part2.rar (64.27 Кб - загружено 711 раз.)
Записан
fly
Гость
« Ответ #10 : 01-08-2008 00:37 » 

Допустим, мне надо включить в DLL-ку какую-то часть работы со стандартными компонентами.
В DLL, это как реализовать? Специальные заголовочные ф-лы нужно использовать?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #11 : 01-08-2008 05:04 » 

Код:
Ошибка была в том, что нужно было поставить знак "_" перед вызовом ф-ии:

при чём тут это, может просто имя у функции такое было ? )
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 01-08-2008 05:28 » 

Underscore character (_) is prefixed to names, except when exporting __cdecl functions that use C linkage.
оно?
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #13 : 01-08-2008 06:45 » 

Народ, не забываем, что речь идет о Borland, а там реально надо эти черточки ставить (сам на Борланде никогда не писал, а вот использовать dll написанные на Борланд приходилось), помоему их компилятор сам для экспортируемых функций проставляет (или что-то в этом роде), для чего - не спрашивайте - не знаю
Записан

С уважением Lapulya
fly
Гость
« Ответ #14 : 01-08-2008 06:58 » 

Вад, да оно.

Алексей1153++, имя ф-ии было без "_"

Это кто-то делал(?):
Цитата
Допустим, мне надо включить в DLL-ку какую-то часть работы со стандартными компонентами.
В DLL, это как реализовать? Специальные заголовочные ф-лы нужно использовать?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 01-08-2008 07:04 » 

fly, насчет последнего: поройся в этом разделе в недавних темах - было уже. Можно выносить часть проекта в dll. В том числе и GUI.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines