处理DLL在尝试使用函数时引发访问冲突0x06efff08。

huangapple go评论79阅读模式
英文:

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.

英文:

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(&#39;E:\D11 Projects\Test Dll\Win32\Debug\BOUsers.Dll&#39;);
  if LHandle &lt;&gt; 0 then
  begin
    @LUserList := GetProcAddress(LHandle, &#39;ShowUserList&#39;);
    if @LUserList &lt;&gt; nil then
    begin
     LForm := LUserList; //Here is where error shows, doesn&#39;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(&#39;UsersListForm&#39;) THEN
        BEGIN
          UsersListForm := TUsersListForm.Create(Application);
          Result        := UsersListForm;
        END
      ELSE
        Result := G.ReturnForm(&#39;UsersListForm&#39;);
    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.

答案1

得分: 0

你没有提到,但你正在运行什么操作系统?是Win XP吗?你试图将应用迁移到Win 10还是11?

我之所以问是因为我不确定D11是否能在Win XP上运行,所以如果你能从最新版本的Delphi(D11)中访问在D6中创建的DLL,我会感到非常惊讶。

我认为你最好的选择是先获得DLL的源代码,然后在D11中重新构建它。如果无法做到这一点,如果它来自第三方供应商,可以考虑获取更新的版本。

如果你没有源代码,那么除了重新编写它或替换为等效的库之外,我不太清楚该提出什么建议。(在过去的20年里,肯定有人写过类似的东西!)

在我的上一份工作中,我被要求将一个Delphi应用程序从XP迁移到Win Server 2016。他们认为这只是一个简单的重新编译,但由于DLL无法在Win10上运行,这并不起作用。而且我们根本不符合供应商的许可条款,供应商想要向我们收取巨额费用以提供更新的解决方案。最终,我建议用Delphi本地编写的组件库来替换DLL,这样做既便宜得多,速度也快得多。

根据你下面的要求添加的内容:你没有确切地要求这个,但由于你有源代码,你可以考虑通过将这些DLL转化为使用本地托管的REST服务的微服务(即在你的内部网络中)。这对于不需要精确时序的任务非常适用,并且会简化在其他机器上部署(如果需要的话),而DLL则需要更多的关注。有很多库可以用来在Delphi中构建服务;我对TMS XData有偏爱。他们出售一些在线课程,逐步指导你完成这个过程。(它是他们Biz Components库的一部分。)除非你从DLL中返回PODOs(不太可能),否则将它们迁移到微服务架构应该非常简单。

英文:

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.

huangapple
  • 本文由 发表于 2023年6月12日 19:08:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76456061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定