functiondelphidlldelphi-11-alexandriadelphi-6

Handling DLL causing Access Violation 0x06efff08 when trying to use function


I'm getting an access violation when I try to link to a function within a DLL file. DLL was made in Delphi 6 and we are upgrading to Delphi 11 (wild jump I know). So the code once upon a time worked and somewhere in the many changes to Delphi has come crumbling down. The Delphi environment is running on a Windows 10 machine. The DLL in use has been compiled and built within Delphi 11 (though components have changed). Delphi claims that it can compile and build, if that is where this issue possibly lies I can get more code as I have the source (and project files) for the DLL.

procedure TForm1.Button1Click(Sender: TObject);
type
  TShowUserList = function : TForm; stdcall;
var
 LHandle: THandle;
 LUserList : TShowUserList;
 LForm : TForm;
begin
  LHandle := LoadLibrary('E:\D11 Projects\Test Dll\Win32\Debug\BOUsers.Dll');
  if LHandle <> 0 then
  begin
    @LUserList := GetProcAddress(LHandle, 'ShowUserList');
    if @LUserList <> nil then
    begin
     LForm := LUserList; //Here is where error shows, doesn't even get to the ShowUserList function
    end;
  end;
end;

When debugging, when I get to LForm := LUserList, LUserList is an 'inaccessible value'. Which would make sense as to why the error is occurring.

And within the BOUsers.dll is a UserList form,

FUNCTION ShowUserList : TForm; 
    BEGIN
      IF NOT G.FormExists('UsersListForm') THEN
        BEGIN
          UsersListForm := TUsersListForm.Create(Application);
          Result        := UsersListForm;
        END
      ELSE
        Result := G.ReturnForm('UsersListForm');
    END;

EXPORTS
   ShowUserList;

Debugging doesn't even enter here (I have made sure debugging is enabled for the dll, though it seemingly was by default). I'd be slightly happy if I could get into this code and debug!

I'm aware there isn't the full amount of error handling (not that there was much on the D6 version). However this is just a test project to help figure out the issue in the main application, I can add it if needs be though.

My expectation is that LForm would be the UserListForm within the dll and that I'd be able to display it within a window pane, debug it for issues and use it as expected.

I've tried to look through various similar questions on StackOverflow (though if I've missed one feel free to link it and I will look through it). Copied the example embarcadero supplied.

Honestly, haven't worked with DLL's before past applications were all units and forms within the exe basically.


Solution

  • You didn't mention it, but what OS are you running this on? Win XP by any chance? Are you trying to migrate the app to Win 10 or 11?

    I'm asking because I'm not sure D11 will even run in Win XP, so I'd be very surprised if you could access a DLL created in D6 from code written in the latest version of Delphi (D11).

    I think your best bet is to get the source code for the DLL and rebuild it in D11 first. Short of that, if it's from a 3rd-party vendor, look into getting a newer version.

    If you don't have the source code, then I'm not sure what to suggest other than rewriting it or replacing it with an equivalent library. (Surely someone has written something similar in the past 20 years!)

    At my last job, I was given the task of migrating a Delphi app from XP to Win Server 2016. They thought it would be a simple recompile, but that didn't work as the DLL wouldn't run in Win10. We were not compliant with the vendor's licensing terms anyway, and the vendor wanted to charge us an arm and three legs for a newer solution. I eventually proposed we replace the DLL with a component library written natively in Delphi that ultimately did the job much cheaper and WAY faster.

    ADDED (per your request below): you didn't ask for this exactly, but since you have the source code, you might consider refactoring by turning these DLLs into micro-services using a locally hosted REST service (ie, inside of your intranet). That would work great for things where timing isn't an issue and would simplify the deployment to other machines (if that's even a need) where the DLLs would require more attention. There are lots of libs that can be used to build services with Delphi; I'm partial to TMS XData. There are a couple of online courses they sell that take you step-by-step through the process. (It's part of their Biz Components lib.) Unless you're returning PODOs from the DLLs (not likely) then it should be really straightforward to migrate them to a micro-service architecture.