2009-11-09 5 views
1

имеет функцию, упрощенную ниже, который экспортируется из BPLВозвращаясь строкой из функции BPL

function DoA(amount: currency; var Info: string): Currency; stdcall; 
begin 
    result := amount * 19; 
    Info:= 'Some Text about the result'; 
end; 

его загруженного из основной программы с LoadPackage и GetProcAddress, который хорошо работает для других функций. , но это вызывает множество ошибок при его вызове;

БПЛ Используется с (упрощенный)

bplhandle: HModule; 
    BPLDoA: function (amount: currency; var Info: string): Currency; stdcall; 
    intoStr : string; 

.

begin 
    bplhandle:=LoadPackage('test.bpl'); 
    if bplhandle <> 0 then 
    begin 
    @BPLDoA:=GetProcAddress(bplhandle,'DoA'); 
     if assigned(BPLDoA) then 
     result := BPLDoA(123, intoStr); 
    end; 
end; 

исключение того, что, кажется, происходит в конце процедуры, но исправленный текст возвращается в intoStr (если смотреть с точкой излома)

бы ошибка имеет ничего общего с Info param является var и/или строкой?

Сообщение об ошибке

Проект Project1.exe поднял класс исключения EInvalidPointer с сообщением 'Invalid операции указателя'

благодаря

более

информации> другая функция из того же BPL/устройство отлично работает

function DoB(amount: currency): Currency; stdcall; 
    result := amount * 19; 
end; 

Mad исключения>

класса исключений: EInvalidPointer сообщение исключения: Недопустимая операция указателя.

основной поток ($ 1b7c): 0040276f +013 Project1.exe Система @FreeMem 00404650 + 01c Project1.exe Система @LStrClr 00483814 + 15c Project1.exe Unit1 97 +11 TForm1.Button3Click 00462430 +064 Проект1 .exe управления TControl.Click 0045a870 + 01c Project1.exe StdCtrls TButton.Click

+0

ваша сумма не имеет «вар» на нем – Treby

+0

извините пример разве лучший плохого изменения его –

ответ

6

Вы не настроили свой EXE проект «строить с пакетами времени выполнения.» Найдите это в разделе «пакеты» вашего проекта. (Documentation)

Исключение составляет EInvalidPointer Исключение возникает, когда менеджер памяти пытается освободить то, что он не выделил. Это говорит о том, что у вас есть два разных менеджера памяти. Ваша BPL использует ту, что из пакета RTL, которая появляется в списке «требует» вашего пакета. С другой стороны, ваш EXE использует диспетчер памяти, скомпилированный в модуль EXE.

Исправьте это, сообщив EXE, чтобы использовать пакеты времени выполнения, а затем убедитесь, что пакет RTL находится в списке необходимых пакетов.

+0

Отлично, у меня было ощущение, что это будет что-то простое, спасибо –

1

ли ваша декларация импорта точно соответствовать подписи экспортируемой функции в?

Должно быть так:

DoAProc: function (amount: currency; var Info: string): Currency; stdcall; 
+0

да это делает, добавил подробнее об импорте –

+0

и кажется stdcall; директива отсутствует. –

+0

ах не видел, что, ive добавил, и, похоже, нет никаких изменений –

0

Еще один вариант, если вы не хотите, чтобы вас отправляли дополнительные BPL (которые вы сейчас будете использовать, чтобы ваш основной exe использовал BPL), должен включать в свой блок ShareMem. Проверьте раздел «Обмен памятью» в файле справки Delphi.

мс-помощь: //embarcadero.rs2010/rad/Sharing_Memory.html

+0

В новых версиях Delphi (> = 2009, если я правильно помню) SimpleShareMem следует использовать. Использование shareMem требует развертывания BorlandMM.dll: http://docwiki.embarcadero.com/RADStudio/en/Sharing_Memory –