Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.08.2008, 12:45   #1
Никки
Форумчанин Подтвердите свой е-майл
 
Аватар для Никки
 
Регистрация: 20.11.2007
Сообщений: 500
По умолчанию Взаимодействие DLL и программы

Мне необходимо использовать в DLL функцию которая описана в модуле моей программы! я пытаюсь передать адрес этой функций как параметр-константу в процедуру DLL в результате чего получаю ошибку Privileged instruction. в объявлений и описании функций в моей программе я указал stdcall.
что мне делать в такой ситуации?
Никки вне форума Ответить с цитированием
Старый 05.08.2008, 13:11   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Наверное показать код
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.08.2008, 14:20   #3
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Как-то странно, а почему ее не вынести в эту DLL?
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 05.08.2008, 14:24   #4
Никки
Форумчанин Подтвердите свой е-майл
 
Аватар для Никки
 
Регистрация: 20.11.2007
Сообщений: 500
По умолчанию

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

вот вам код!!
Код:
unit Unit1;

interface

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

type
  TDllProc=procedure(const Addr:Pointer);
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    DllProc:TDllProc;
    hDll:THandle;
  public
    function MyBestFunction:String; stdcall;
  end;

var
  Form1: TForm1;

implementation

function TForm1.MyBestFunction:String; stdcall;
begin
    ShowMessage('Hello Word');
    MyBestFunction:='Hello';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    hDll:=LoadLibrary('BlaBlaBla.dll');
    if hDll>0 then begin
        @DllProc:=GetProcAddress(hDll,'DllProc');
    end;
    if @DllProc<>nil then DllProc(GetProcAddress(Application.Handle,'MyBestFunction'));
{здесь будет ошибка!!}
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    FreeLibrary(hDll);
end;

end.

library lb1;

type
    TMyBestFunction=function:String;
var
    MyBestFunction:TMyBestFunction;

procedure DllProc(const Addr:Pointer) export; stdcall;
begin
        @MyBestFunction:=Addr;
        MyBestFunction;
end;

exports DllProc;

begin
end.

Последний раз редактировалось zetrix; 05.08.2008 в 15:09. Причина: объединение
Никки вне форума Ответить с цитированием
Старый 05.08.2008, 14:54   #5
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Честно говоря я чтот не пойму что здесь ввообще происходит!
По порядку

1. Ехе получает указатель на DllProc
2. Ехе получает указатель на не экспортируемую функцию причем из Application.Handle
3. Полученый непонятный указатель передается функции в dll и вызывается и после чего длл передает управленее коду по данному указателю в памяти.

Сразу вопрос! Функция не постоянна, т.е. если бы вы написали @MyBestFunction вам бы компилятор "показал бы где раки зимууют" так вы решили его обдурить?! Вам вот что надо

Код:
function {не стоит TForm1.}MyBestFunction:String; stdcall;
begin  
    ShowMessage('Hello Word');  
    MyBestFunction:='Hello';  
end;  

procedure TForm1.Button1Click(Sender: TObject);  
begin  
    hDll:=LoadLibrary('BlaBlaBla.dll');  
    if hDll>0 then begin  
        @DllProc:=GetProcAddress(hDll,'DllProc');
    end;  
    if @DllProc<>nil then DllProc(@MyBestFunction);  
{здесь наверное не будет ошибки!!}  
end;
Проверять не проверял, так что может я и ошибся.

Ах да, если уж так надо то попробуйте функции MyBestFunction еще приписать export;
BOBAH13 вне форума Ответить с цитированием
Старый 05.08.2008, 14:59   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Как-то странно, а почему ее не вынести в эту DLL?
Ниче странного. Callback функи довольно популярны в Винде.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.08.2008, 15:17   #7
Никки
Форумчанин Подтвердите свой е-майл
 
Аватар для Никки
 
Регистрация: 20.11.2007
Сообщений: 500
По умолчанию

BOBAH13, то же самое сообщение в том же самом месте!
Мне кажется что у Dll нет прав работать с областью памяти приложения... или это не так?
Никки вне форума Ответить с цитированием
Старый 05.08.2008, 15:19   #8
Никки
Форумчанин Подтвердите свой е-майл
 
Аватар для Никки
 
Регистрация: 20.11.2007
Сообщений: 500
По умолчанию

Хотя теперь @MyBestFunction как параметр у меня прокатило, хотя раньше было сообщение об ошибке, вот я и сделал через GetProcAddress.
Никки вне форума Ответить с цитированием
Старый 05.08.2008, 15:30   #9
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Я уверен на 99% что в сообщения об ошибки сообщалось, что требуется переменна или функция которая указывается параметру @ не является постоянной, т.е. зависима от класса. А мы теперь убрали зависимость от класса и функция просто загружена в память и имеет указатель, в коде он является просто MyBestFunction

p.s. так работает или нет ? чет я не понял )))
BOBAH13 вне форума Ответить с цитированием
Старый 05.08.2008, 16:00   #10
DearHunter
Пользователь
 
Регистрация: 30.07.2008
Сообщений: 14
По умолчанию

В дельфи при передаче строки между модулями в качестве параметра или результата функции, необходимо использовать библиотеку менеджера памяти borlndmm.dll, указывая ShareMem первым в списке юнитов обоих проектов, как сказано ниже (из сгенерированного проекта dll).

{ 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. }

Если в Ваших проектах это уже сделано - попытайтесь сначала вызвать функцию, имеющую параметры и результат примитивных типов.
DearHunter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Взаимодействие flash и C#? mrakaziabra Общие вопросы .NET 3 16.07.2008 07:16
взаимодействие с QIP Toxa Общие вопросы Delphi 5 20.06.2008 19:39
Взаимодействие с виндой и еще кое-что Manitu Помощь студентам 5 25.03.2008 09:28