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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рабочая функция генерит ошибку, при вызове её из Dll 
:(
    Опции темы
Poseidon
  Дата 15.9.2005, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


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

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



Вот незадача.
Есть функция, каторая при помещении ее в .exe работает на УРА. Но стоит ее поместить в Dll, как все летит.

Dll:
Код
library Lan;

uses
  SysUtils,
  WinSock;

{$R *.res}

function HostToIP(name: string): string; stdcall;
var
  wsdata : TWSAData;
  hostName : array [0..255] of char;
  hostEnt : PHostEnt;
  addr : PChar;
begin
  WSAStartup ($0101, wsdata);
  try
    gethostname (hostName, sizeof (hostName));
    StrPCopy(hostName, name);
    hostEnt := gethostbyname (hostName);
    if Assigned (hostEnt) then
      if Assigned (hostEnt^.h_addr_list) then begin
        addr := hostEnt^.h_addr_list^;
        if Assigned (addr) then begin
          Result := Format ('%d.%d.%d.%d', [byte(addr[0]),
          byte (addr [1]), byte (addr [2]), byte(addr[3])]);
        end
        else
          Result := '';
      end
      else
        Result := ''
    else begin
      Result := '';
    end;
  finally
    WSACleanup;
  end
end;


exports
HostToIP;

begin
end.


.exe

Код
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type THostToIP = function (name: string): string; stdcall;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
HostToIP: THostToIP;
LanDll: THandle;
begin
LanDll:= LoadLibrary('Lan.dll');
@HostToIp:= GetProcAddress(LanDll, 'HostToIP');
Form1.Caption:= HostToIP('');
FreeLibrary(LanDll);
end;

end.


C чего бы это? smile


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
p0s0l
Дата 15.9.2005, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Помести ShareMem в USES-часть DLL-ки и USES-часть проекта (*.dpr). Важная деталь: ShareMem должен быть первым в списке подключаемых модулей!
Добавлено @ 18:52
Цитата(Poseidon @ 15.9.2005, 18:13)
C чего бы это?
Когда делаем File->New->Other->DLL Wizard:
Код

library Project1;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes;

{$R *.res}

begin
end.




--------------------
С уважением, г-н Посол.
PM   Вверх
Poseidon
Дата 15.9.2005, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


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

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



Спасибо p0s0l, но это вариант не подойдет по двум причинам:
1). Размер ДЛЛ увеличился с 91 до 234 Кб. (У лучше тогда подключить WinSock к exe и создать функцию там)
2) Функция выполняется, но при закрытии программы вылетает "Invalid pointer operation"

Мне даже не нужно готовый рабочий пример давать. Мне бы понять, почему так происходит. Ведь, если эта функция зашита в exe, то все нормально работает.

Понять бы почему ошибка, тогда и разобратся с ней было бы легче.

PS. А что это за модуль такой ShareMem? Зачем он?

Это сообщение отредактировал(а) Poseidon - 15.9.2005, 18:55


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
p0s0l
Дата 15.9.2005, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Цитата(Poseidon @ 15.9.2005, 18:54)
2) Функция выполняется, но при закрытии программы вылетает "Invalid pointer operation"
Значит не туда или не везде воткнул ShareMem...

Цитата(Poseidon @ 15.9.2005, 18:54)
PS. А что это за модуль такой ShareMem? Зачем он?
Цитата(Help)
ShareMem is the interface unit for the BORLANDMM.DLL memory manager, which allows modules to share dynamically allocated memory.
Более подробно - открой DRKB и в поиске напиши ShareMem smile
Например:
Цитата(DRKB)
Первый вопрос возникающий при создании библиотеки (DLL): А что это тут написано в закомментированной части исходного кода библиотеки. А рассказывается там следующее — если вы используете динамические массивы, длинные строки (что и является динамическим ма ссивом) как результат функции, то необходимо чтобы первым в секции uses стоял модуль ShareMem. Причём и в основном проекте! От себя добавлю, что это относится более широко к тем случаям, когда вы выделяете память в одной библиотеке, а освобождаете в друго й, что и произойдёт когда вы создадите динамический массив в одной Dll-ке, а освободите его в другой.

Использовать ли ShareMem — вопрос конкретной постановки задачи. Если можно обойтись без таких выделений памяти, то вперёд, с песней! Иначе придётся вместе с программой таскать borlndmm.dll, которая и реализует безболезненный обмен указателями между библио теками.


Цитата
1). Размер ДЛЛ увеличился с 41 до 234 Кб. (У лучше тогда подключить WinSock к exe и создать функцию там)
Тогда придётся отказаться от передачи динамических строк и массивов... Самое простое - в общем случае передавать в функцию адрес буфера (ну и размер буфера), куда функция должна поместить результат...
В твоём же случае (IP-адрес и имя машины) можно использовать ShortString вместо string...
Добавлено @ 19:10
Так же Петрович когда-то упоминал альтернативу ShareMem - FastSharemem, тогда DLL-ку с собой таскать не надо... Я не юзал, но можешь попробовать...


--------------------
С уважением, г-н Посол.
PM   Вверх
Poseidon
Дата 15.9.2005, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


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

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



Благодарствую. Немного покапавшись в указанном табою направлении с ошибкой справился. smile


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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