Recent

Author Topic: Statically loaded DLL works, dynamically crashes and still works.  (Read 3944 times)

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/


When I load a DLL dynamically it works just fine. When I load it dynamically, it generates a exception (External :SIGSEGV) , but it still works the following way:
I run several functions in a procedure. All of them generate exceptions (or I suppose so,because I added try.... except to each of them and except code is executed on each of them) , but the procedure does what it should. Alas, in the end of the procedure I get an exception message and the application  closes, and I cannot prevent it from doing so. >:D 
I load the DLL statically this way
Code: [Select]
unit Cbw;
{$MODE Delphi}
{$D+,S+,L+}   
interface

const 
...
function cbGetStatus (BoardNum:Integer; var Status:SmallInt; var CurCount:Longint; var CurIndex:Longint;FunctionType:Integer):Integer; StdCall;
function cbStopBackground (BoardNum:Integer;FunctionType:Integer):Integer; StdCall;
...
implementation
...
function cbGetStatus; external 'CBW32.DLL' name 'cbGetIOStatus';
function cbStopBackground; external 'CBW32.DLL' name 'cbStopIOBackground'; 
...
 
           

And I load it dynamically this way:
Code: [Select]
unit cbw_dyn;
{$MODE objfpc}
...
type

...
  TcbGetStatus=function  (BoardNum:Integer; var Status:SmallInt; var CurCount:Longint; var CurIndex:Longint;FunctionType:Integer):Integer; StdCall;
  TcbStopBackground=function  (BoardNum:Integer;FunctionType:Integer):Integer; StdCall;
...
var
 DllHandle: THandle;
...
  cbGetStatus:TcbGetStatus;
  cbStopBackground:TcbStopBackground;
...
    cbGetStatus:=           TcbGetStatus(GetProcedureAddress        (DLLHandle, 'cbGetStatus'));
    cbStopBackground:=   TcbStopBackground(GetProcedureAddress        (DLLHandle, 'cbStopBackground'));
...
         


The loading procedure is:
 
Code: [Select]
        function LoadMCCLib: Boolean; //True if successful
begin
   if DllHandle = NilHandle then DllHandle := SafeLoadLibrary('cbw32.dll');
   if DLLHandle <> NilHandle then
   begin     
...
      cbGetStatus:=           TcbGetStatus(GetProcedureAddress        (DLLHandle, 'cbGetStatus'));
      cbStopBackground:=   TcbStopBackground(GetProcedureAddress        (DLLHandle, 'cbStopBackground'));
...
end;
 
         
Am I doing something wrong?
Or at least a hint how to ignore the exception might do.
« Last Edit: April 15, 2014, 10:27:05 am by paskal »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Statically loaded DLL works, dynamically crashes and still works.
« Reply #1 on: April 15, 2014, 10:29:05 am »
You should probably leave out this part:
Code: [Select]
function cbGetStatus; external 'CBW32.DLL' name 'cbGetIOStatus';
function cbStopBackground; external 'CBW32.DLL' name 'cbStopIOBackground'; 

In FPC static declarations must be specified in the interface section b.t.w.

You can take a look at the (Windows) implementation of GetAppConfigDir() to see how it dynamically loads the library (forgot it's name) to query where common Windows folders are, and how it then connects the functions.

Bart

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Statically loaded DLL works, dynamically crashes and still works.
« Reply #2 on: April 15, 2014, 12:51:28 pm »
Maybe I should mention, that in some cases I have no problems with the same DLL dynamically loaded, but probably I got to ussing functions, whch cause problems.



You should probably leave out this part:
Code: [Select]
function cbGetStatus; external 'CBW32.DLL' name 'cbGetIOStatus';
function cbStopBackground; external 'CBW32.DLL' name 'cbStopIOBackground'; 
My idea is to leave out the entire static loading, but if I fail, I might clean up.


 

You can take a look at the (Windows) implementation of GetAppConfigDir() to see how it dynamically loads the library (forgot it's name) to query where common Windows folders are, and how it then connects the functions.
I could not find it, but I found ..\lazarus\lcl\interfaces\wince\winext.pas.
I see no difference from my code, except that the use DllHandle: HINST; while I use  DllHandle: THandle;
I have no idea what HINST is, but I doubt it could change anything?
« Last Edit: April 15, 2014, 01:29:13 pm by paskal »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

sarason

  • Jr. Member
  • **
  • Posts: 77
Re: Statically loaded DLL works, dynamically crashes and still works.
« Reply #3 on: April 24, 2014, 03:19:15 am »
Did you try loading your DLL in Dependency Walker or better still PE Explorer to make sure it is of the required type. ie Stdcall, Pascal, Extern 'C', not mangled, etc on both sides ie your Pascal and your DLL agree on the calling convention.

Also look at the DLL in a hex editor and make sure your NE is in the right place ie at $80H.

In the bad old days moving NE around was a cheats way of making a DLL uncallable by someone else's code.

sarason

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Statically loaded DLL works, dynamically crashes and still works.
« Reply #4 on: April 24, 2014, 05:21:08 am »
I think you made a small mistake and as a result each and every call to GetProcedureAddress fails. You wrote that you used this code to use the library statically:
Code: [Select]
...
function cbGetStatus; external 'CBW32.DLL' name 'cbGetIOStatus';
function cbStopBackground; external 'CBW32.DLL' name 'cbStopIOBackground'; 
...
and it works.

While when you use this code:
Code: [Select]
...
 cbGetStatus:= TcbGetStatus(GetProcedureAddress(DLLHandle, 'cbGetStatus'));
 cbStopBackground:= TcbStopBackground(GetProcedureAddress(DLLHandle, 'cbStopBackground'));
...
It does not work.

Instead of using 'cbGetIOStatus' you used 'cbGetStatus'
and for 'cbStopIOBackground' you used 'cbStopBackground'
Put back the 'IO' letters in these names, will you?  :P

 

TinyPortal © 2005-2018