【问题标题】:The results from DLL in Delphi where the parameters are PAnsiCharDelphi中DLL的结果,其中参数为PAnsiChar
【发布时间】:2021-01-09 14:17:45
【问题描述】:

我有一个小问题。 在我的 DLL 中,我有:

uses
  ShareMem,
  SysUtils,
  Classes,
  Dialogs;

function My_func (Param1, Param2, Param3: PAnsiChar) : Integer;

var
  s1,s2,s3 : string;

begin

     s1 := string(Param1);
     s2 := string(Param2);
     s3 := string(Param3);
     ShowMessage(s1);
     ShowMessage(s2);
     ShowMessage(s3);

     My_func := 0;
end;

还有来自我的 TestUnit.pas 的调用

unit Utestunit;

interface

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

procedure Button1Click(Sender: TObject);
type
  TMy_func = function (Param1, Param2, Param3: PAnsiChar) : Integer; StdCall;
var
  my_func : TMyfunc;

  error_code:integer;
  My_library : THandle;
  the_end : Boolean;
  path_library,
  path_library_full : string;

  test1,
  test2,
  test3 : array [0..255] of AnsiChar;
begin
  // open the DLL
  path_library := ExtractFilePath(Application.ExeName)+'DLL\RS_DLL.dll';
  path_library_full := ExtractFilePath(Application.ExeName)+'DLL\';
  SetCurrentDir(path_library_full);
  try
    the_end := False;
    My_library := SafeLoadLibrary(PChar(path_library));
    if My_library > 32 then
    begin
        @My_func := GetProcAddress(My_library, PChar('My_func'));
        if @My_func = nil then
        begin
          ShowMessage('There is no library in '+path_library);
          the_end := True;
        end;
    end
    else
    begin
      error_code := GetLastError;
      ShowMessage('Błąd biblioteki '+ sciezka_biblioteki+' nr:'+IntToStr(error_code));
      the_end := True;
    end;

    if not the_end then
    begin
      // the calling

      test1 := 'My string nr 1';
      test2 := 'My string nr 2';
      test3 := 'My string nr 3';

      kod_bledu := My_func(
          test1,
          test2,
          test3
      );      
    end;

  finally
    FreeLibrary(My_library);
    SetCurrentDir(ExtractFilePath(Application.ExeName))
  end;
end;

结果是:

My string nr 1

trash

trash

作为来自我的 DLL 的消息。

为什么只有第一个结果是好的,而其余的垃圾是? 这只是我的应用程序中的测试。

【问题讨论】:

    标签: delphi delphi-2010


    【解决方案1】:

    这段代码中有很多非常不好的习惯,我不想去处理,因为这需要付出很多努力。

    但是,该行为的原因是您没有在 DLL 中将函数声明为 stdcall。修复它,文本将正确传递。

    【讨论】:

    • 谢谢大卫。你说得对,错过了“stdcall”。顺便说一句,你看到了什么“坏习惯”?该库是动态加载的,我需要的字符串在 PAnsiChar.... 所以呢?
    • 使用 Sharemem 毫无意义。无需使用那些固定长度的数组。加载 DLL 的代码是完全错误的。对 32 的检查是错误的。有一篇蹩脚的博客文章,人们多年来一直在复制该代码。
    • @DavidHeffernan 我确信基于该博客文章的软件已售出并存在于野外。甚至可能在驱动程序中。
    • @DavidHeffernan 你会这么好心并介绍在Delphi中处理DLL的“正确方法”吗?也许寻找好的解决方案的人会阅读这篇文章并使用您的建议。在我决定在这里发帖之前,我已经在许多互联网页面上寻找解决方案,并且我看到了很多例子,但我不会被允许批评。当某些解决方案运作良好时 - 它是正确的解决方案。但如果有更好的 - 向其他阅读本文的人展示(分享)它是正确的。
    • 阅读LoadLibrary 的文档。没有提到这个幻数 32。如果函数失败,它会返回 NULL,也就是 0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多