Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Статическое подключение dll, Точка входа не найдена 
:(
    Опции темы
Norfonzor
Дата 23.12.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 17.10.2008

Репутация: нет
Всего: нет



New -> other -> DllWizard
код длл:
Код

library mydll;

uses
  SysUtils,
  Classes;
const n=100;
{$R *.res}

function Prostoe4islo(n: integer):boolean; stdcall;
var
ok:boolean;

i,j:integer;

begin
ok:=true;
if (n<=0)or(n=2) then ok:=false;


if n>=3 then
for i:=2 to (n-1) do
begin
if round(n/i)-(n/i)=0 then ok:=false;
end;

if ok=false then result:=false else result:=true;
end;

{Директива exports указывает, какие функции будут экспортированы этой DLL}
exports Prostoe4islo;

begin
end.


нажимаю F9
вылазит:user posted image
Dll создается

далее close

new aplication
код:
Код

program MainWindow;

uses
  Windows,
  Messages,
  SysUtils;

const
  id_Button = 1;
  id_Edit = 2;




function prostoe4islo(n:integer):boolean; stdcall; external 'MYDLL.DLL';


function PlainWinProc (hWnd: THandle; nMsg: UINT;
  wParam, lParam: Cardinal): Cardinal; export; stdcall;
var
  Rect: TRect;
  s1, s2, s_c: array [0..127] of Char;
  n1, n2:integer;


begin

  Result := 0;
  case nMsg of
    wm_Create:
      begin

      GetClientRect (hWnd, Rect);

      CreateWindowEx (0,
                      'button',
                      '&OK',
                       ws_Child or ws_Visible or ws_Border or bs_PushButton,
                       Rect.Left + 120, Rect.Top + 10,
                       100, 20,
                       hwnd,
                       id_Button,
                       hInstance,
                       nil);

       CreateWindowEx (0,
                      'Edit',
                       '',
                       ws_Child or ws_Visible or ws_Border or es_Number,
                       Rect.Left + 10, Rect.Top + 10,
                       100, 20,
                       hwnd,
                       id_Edit,
                       hInstance,
                       nil);
       SetWindowText(GetDlgItem (hWnd, id_Edit),'0');
       end;
   wm_Command:
   begin
      if LoWord (wParam) = id_Button then
        if HiWord (wParam) = bn_Clicked then
          begin
            GetWindowText(GetDlgItem (hWnd, id_Edit), s1, GetWindowTextLength(GetDlgItem (hWnd, id_Edit))+1);
            //MessageBox (hWnd, '', 'Ðåçóëüòàò', MB_OK)

            if Prostoe4islo(strtoint(s1))then MessageBox (hWnd, 'Простое!', 'Результат', MB_OK);
           end;
   end;
    wm_Destroy:
      PostQuitMessage (0);
    else
      Result := DefWindowProc (hWnd, nMsg, wParam, lParam);
  end;
end;

procedure WinMain;
var
  hWnd: THandle;
  Msg: TMsg;
  WndClassEx: TWndClassEx;
begin

  WndClassEx.cbSize := sizeOf (TWndClassEx);
  WndClassEx.lpszClassName := 'PlainWindow';
  WndClassEx.style := cs_VRedraw or cs_HRedraw;
  WndClassEx.hInstance := HInstance;
  WndClassEx.lpfnWndProc := @PlainWinProc;
  WndClassEx.cbClsExtra := 0;
  WndClassEx.cbWndExtra := 0;
  WndClassEx.hIcon := LoadIcon (hInstance,
    MakeIntResource ('MAINICON'));
  WndClassEx.hIconSm  := LoadIcon (hInstance,
    MakeIntResource ('MAINICON'));
  WndClassEx.hCursor := LoadCursor (0, idc_Arrow);;
  WndClassEx.hbrBackground := GetStockObject (white_Brush);
  WndClassEx.lpszMenuName := nil;

  if RegisterClassEx (WndClassEx) = 0 then
    MessageBox (0, 'Invalid class registration',
      'Plain API', MB_OK)
  else
  begin
    hWnd := CreateWindowEx (
      WS_SIZEBOX,
      WndClassEx.lpszClassName,
      'Ïóñòîå îêíî',
      ws_OverlappedWindow,
      cw_UseDefault, cw_UseDefault,
      240, 300,
      0,
      0,
      HInstance,
      nil);
    if hWnd = 0 then
      MessageBox (0, 'Window not created',
        'Plain API', MB_OK)
    else
    begin
      ShowWindow (hWnd, sw_ShowNormal);
      while GetMessage (Msg, 0, 0, 0) do
      begin
        TranslateMessage (Msg);
        DispatchMessage (Msg);
      end;
    end;
  end;
end;

begin
  WinMain;
end.



подключаю длл статически через:

Код

function prostoe4islo(n:integer):boolean; stdcall; external 'MYDLL.DLL';


и вызываю ф-ию через: 
Код

 if Prostoe4islo(strtoint(s1))then MessageBox (hWnd, 'Простое!', 'Результат', MB_OK);


вылазит:
user posted image

Сломал голову, в чем ошибка?
Да еще если стереть строчку 
Код

if Prostoe4islo(strtoint(s1))then MessageBox (hWnd, 'Простое!', 'Результат', MB_OK);
 то прога комплитица

Сейчас попробую еще подключить динамически. 

Динамически:
Код длл такойже

Мэйн:
Код

program MainWindowsDin;

uses
  Windows,
  Messages,
  SysUtils;

const
  id_Button = 1;
  id_Edit = 2;



function PlainWinProc (hWnd: THandle; nMsg: UINT;
  wParam, lParam: Cardinal): Cardinal; export; stdcall;
var
  Rect: TRect;
  s1, s2, s_c: array [0..127] of Char;
  n1, n2:integer;
  prostoe4islo: function(n:integer):boolean;
  LibHandle: THandle;

begin

  Result := 0;
  case nMsg of
    wm_Create:
      begin

      GetClientRect (hWnd, Rect);

      CreateWindowEx (0,
                      'button',
                      '&OK',
                       ws_Child or ws_Visible or ws_Border or bs_PushButton,
                       Rect.Left + 120, Rect.Top + 10,
                       100, 20,
                       hwnd,
                       id_Button,
                       hInstance,
                       nil);

       CreateWindowEx (0,
                      'Edit',
                       '',
                       ws_Child or ws_Visible or ws_Border or es_Number,
                       Rect.Left + 10, Rect.Top + 10,
                       100, 20,
                       hwnd,
                       id_Edit,
                       hInstance,
                       nil);
       SetWindowText(GetDlgItem (hWnd, id_Edit),'0');
       end;
   wm_Command:
   begin
      if LoWord (wParam) = id_Button then
        if HiWord (wParam) = bn_Clicked then
          begin
            GetWindowText(GetDlgItem (hWnd, id_Edit), s1, GetWindowTextLength(GetDlgItem (hWnd, id_Edit))+1);


            //MessageBox (hWnd, '', 'Результат', MB_OK)

            @Prostoe4islo := nil;
            LibHandle := LoadLibrary('MYDLL.DLL');
            {Если все OK}
            if LibHandle <= 32 then MessageBox (hWnd, 'Ошибка 1', 'ошибка', MB_OK);

            @Prostoe4islo := GetProcAddress(LibHandle,'Prostoe4islo');
            {Если и здесь все OK}
            if @Prostoe4islo <> nil then
            begin
            {...то вызываем эту функцию и показываем результат}

            if Prostoe4islo(strtoint(s1)) then MessageBox (hWnd, 'Число простое!', 'Результат', MB_OK) else
            MessageBox (hWnd, 'Число НЕ простое!', 'Результат', MB_OK);
            end else MessageBox (hWnd, 'Ошибка 2', 'ошибка', MB_OK);

            FreeLibrary(LibHandle);

           end;
   end;
    wm_Destroy:
      PostQuitMessage (0);
    else
      Result := DefWindowProc (hWnd, nMsg, wParam, lParam);
  end;
end;

procedure WinMain;
var
  hWnd: THandle;
  Msg: TMsg;
  WndClassEx: TWndClassEx;
begin

  WndClassEx.cbSize := sizeOf (TWndClassEx);
  WndClassEx.lpszClassName := 'PlainWindow';
  WndClassEx.style := cs_VRedraw or cs_HRedraw;
  WndClassEx.hInstance := HInstance;
  WndClassEx.lpfnWndProc := @PlainWinProc;
  WndClassEx.cbClsExtra := 0;
  WndClassEx.cbWndExtra := 0;
  WndClassEx.hIcon := LoadIcon (hInstance,
    MakeIntResource ('MAINICON'));
  WndClassEx.hIconSm  := LoadIcon (hInstance,
    MakeIntResource ('MAINICON'));
  WndClassEx.hCursor := LoadCursor (0, idc_Arrow);;
  WndClassEx.hbrBackground := GetStockObject (white_Brush);
  WndClassEx.lpszMenuName := nil;

  if RegisterClassEx (WndClassEx) = 0 then
    MessageBox (0, 'Invalid class registration',
      'Plain API', MB_OK)
  else
  begin
    hWnd := CreateWindowEx (
      WS_SIZEBOX,
      WndClassEx.lpszClassName,
      'Пустое окно',
      ws_OverlappedWindow,
      cw_UseDefault, cw_UseDefault,
      240, 300,
      0,
      0,
      HInstance,
      nil);
    if hWnd = 0 then
      MessageBox (0, 'Window not created',
        'Plain API', MB_OK)
    else
    begin
      ShowWindow (hWnd, sw_ShowNormal);
      while GetMessage (Msg, 0, 0, 0) do
      begin
        TranslateMessage (Msg);
        DispatchMessage (Msg);
      end;
    end;
  end;
end;

begin
  WinMain;
end.



  объявляю длл и ф-ию:
Код

  prostoe4islo: function(n:integer):boolean;
  LibHandle: THandle;


подключаю длл через:
Код

           @Prostoe4islo := nil;
            LibHandle := LoadLibrary('MYDLL.DLL');
            if LibHandle <= 32 then MessageBox (hWnd, 'Ошибка 1', 'ошибка', MB_OK);
            @Prostoe4islo := GetProcAddress(LibHandle,'Prostoe4islo');
            if @Prostoe4islo <> nil then


обращаюсь к ф-ии
Код

          begin
            if Prostoe4islo(strtoint(s1)) then MessageBox (hWnd, 'Число простое!', 'Результат', MB_OK) else
            MessageBox (hWnd, 'Число НЕ простое!', 'Результат', MB_OK);
          end 
          else MessageBox (hWnd, 'Ошибка 2', 'ошибка', MB_OK);


отключаю длл
Код

FreeLibrary(LibHandle);


ошибок никаких не выдает, но ккаое бы число я не вписал то всегда ответ одинаковый:
'Число НЕ простое!'
код проверки числа на простоту проверял создав обычный проект, числа распознает.

в чем здесь косяк??

Это сообщение отредактировал(а) Norfonzor - 23.12.2009, 21:08
PM MAIL   Вверх
Alexeis
Дата 23.12.2009, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Можно попробовать так.
Код

function prostoe4islo(n:integer):boolean; stdcall; external 'MYDLL.DLL' name 'prostoe4islo';


Я бы для порядка посмотрел секцию экспорта у Dll и проверил есть ли там такая функция.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Norfonzor
Дата 23.12.2009, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 17.10.2008

Репутация: нет
Всего: нет



Alexeis, 
изменил в MainWindow
Код

function prostoe4islo(n:integer):boolean; stdcall; external 'MYDLL.DLL';

на
Код

function prostoe4islo(n:integer):boolean; stdcall; external 'MYDLL.DLL' name 'prostoe4islo';


ошибка остается

а про проверить ф-ии в exports строчка 
Код

exports Prostoe4islo;

в Mydll присутствует. да еще при открытии длл через open project
вылазит ошибка: 
user posted image
но проект открывается, при закрытии спрашивает сохранить ли проект, спрашивает даже если код я не правил.

вот ссылка на проект мб станет понятно в чем проблема 
http://depositfiles.com/files/mq2c6gqn8

Это сообщение отредактировал(а) Norfonzor - 23.12.2009, 21:22
PM MAIL   Вверх
Alexeis
Дата 23.12.2009, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Norfonzor, лучше приатачьте саму dll, я гляну ее экспорт.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
bems
Дата 23.12.2009, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Регистр не совпадает.
Ты экспортируешь с большой буквы, оно и ищется с большой.
Языку дельфи пофиг на регистр, но к системным функциям ищущим экспортируемый символ в длл в длл это не относится.
А ошибка про res-файл не имеет отношения, это другое.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Alexeis
Дата 23.12.2009, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(bems @  23.12.2009,  20:56 Найти цитируемый пост)
Регистр не совпадает.

Угу ток что проверил справку по GetProcAddress
Цитата

The spelling and case of a function name pointed to by lpProcName must be identical to that in the EXPORTS statement of the source DLL's module-definition (.def) file

Т.е. регистр имеет значение. Причем важен регистр именно тут
> name 'prostoe4islo';


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Демо
Дата 23.12.2009, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 30
Всего: 50



Скопируй имя функции из её определения везде и снова попробуй.


Код

library mydll;

uses
  SysUtils,
  Classes;
const n=100;

function Prostoe4islo(n: integer):boolean; stdcall;
var
  i: Integer;
begin
  Result := (n<=0) or (n=2);

  if n>=3 then
  begin
    for i:=2 to (n-1) do
    begin
      if round(n/i)-(n/i)=0 then
      begin
        Result := False;
        Exit;
      end;
    end;
  end;
end;
exports Prostoe4islo;
begin
end.

Кстати у тебя лишние вычисления. Проверять деление нужно до (n div 2), и даже до квадратного корня из n.


--------------------
    
PM MAIL ICQ Skype   Вверх
bems
Дата 23.12.2009, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(Alexeis @  23.12.2009,  21:59 Найти цитируемый пост)
Т.е. регистр имеет значение. Причем важен регистр именно тут
> name 'prostoe4islo'; 

да, но если исправить раньше, то name 'prostoe4islo' можно и выкинуть

Это сообщение отредактировал(а) bems - 23.12.2009, 22:09


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Alexeis
Дата 23.12.2009, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(bems @  23.12.2009,  21:08 Найти цитируемый пост)
да, но если исправить раньше, то name 'prostoe4islo' можно и выкинуть

  Но ИМХО лучше когда имя указано явно. Чисто для порядка. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Norfonzor
Дата 24.12.2009, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 17.10.2008

Репутация: нет
Всего: нет



Спасибо, большое, статическое подключение работает и ответ выдает правильный, а вот динамическое не хочет, всегда выдает что число не простое, даже вбивал на прямую в ф-ию простые числа, ф-ия возращает false всегда. здесь ошибка уже ведь не в длл. Имя ф-ии везде изменил с маленькой буквы.
PM MAIL   Вверх
bems
Дата 24.12.2009, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(Norfonzor @  23.12.2009,  20:18 Найти цитируемый пост)
if LibHandle <= 32 then MessageBox (hWnd, 'Ошибка 1', 'ошибка', MB_OK);
Проверяй на равенство нулю. Если не 0, то всегда будет значительно больше тридцати двух. 

А про неверный результат:
Цитата(Norfonzor @  23.12.2009,  20:18 Найти цитируемый пост)
prostoe4islo: function(n:integer):boolean;

Цитата(Norfonzor @  23.12.2009,  20:18 Найти цитируемый пост)
function Prostoe4islo(n: integer):boolean; stdcall;
Найди одно отличие



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Alexeis
Дата 24.12.2009, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



  На всякий случай поясню stdcall определяет метод передачи параметров и возвращения результата, именно поэтому функция возвращала неверный результат.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Norfonzor
Дата 25.12.2009, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 17.10.2008

Репутация: нет
Всего: нет



 smile  Работает! bems и Alexeis, спасибо огромное! мог бы поставить плюсы, поставил!

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1434 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.