【问题标题】:delphi calling AMD ADL c++ dlldelphi 调用 AMD ADL c++ dll
【发布时间】:2012-10-31 04:58:31
【问题描述】:

尝试与 AMD ADL 库 (DLL) 交互以检索显卡上的信息。有一些功能可以工作,但有问题。

请查看此帖子,有相同的问题但没有答案:ATI ADL - AdapterInfo_Get

函数使用delphi数组返回但内容错误。
该函数使用指向缓冲区的指针返回,但数据相同[错误]。
[参见下面的代码示例]

该函数在文档中定义如下:

int ADL_Adapter_AdapterInfo_Get(LPAdapterInfo   lpInfo,   int  iInputSize)          


Retrieves all OS-known adapter information. 

This function retrieves the adapter information of all OS-known adapters in the
system. OS-known adapters can include adapters that are physically present in the  
system (logical adapters) as well as ones that are no longer present in the system   
but are still recognized by the OS.

Supported Platforms:
Linux and Windows(XP, Vista and Windows 7); 32bit and 64bit 

Parameters:
[in]    iInputSize  The size of the lpInfo buffer. 
[out]   lpInfo  The pointer to the buffer containing the retrieved adapter information. 

Returns:
If the function succeeds, the return value is ADL_OK. Otherwise the return value is an ADL error code. Result Codes

Remarks:
This API take a fixed-size output array. For dynamic-size output, use ADL_Adapter_AdapterInfoX2_Get function. 

adl_structures.pas 文件定义 AdapterInfo 如下: 输入

  AdapterInfo = record
    iSize : integer;
    iAdapterIndex : integer;
    strUDID : array [0..ADL_MAX_PATH] of char;
    iBusNumber : integer;
    iDeviceNumber : integer;
    iFunctionNumber : integer;
    iVendorID : integer;
    strAdapterName : array [0..ADL_MAX_PATH] of char;
    strDisplayName : array [0..ADL_MAX_PATH] of char;
    iPresent : integer;

   {$IFDEF MSWINDOWS}
    iExist : Integer;
    strDriverPath : array [0..ADL_MAX_PATH-1] of Char;
    strDriverPathExt : array[0..ADL_MAX_PATH-1] of Char;
    strPNPString : array[0..ADL_MAX_PATH-1] of char;
    iOSDisplayIndex : integer;  
   {$ENDIF} { (_WIN32) || (_WIN64) }

  end;
  LPAdapterInfo = ^AdapterInfo;

我以这种方式为每个函数声明了一个类型:

type
  TADL_MAIN_CONTROL_CREATE = function(param1 : ADL_MAIN_MALLOC_CALLBACK; param2 : integer) : integer; cdecl;
  TADL_MAIN_CONTROL_DESTROY = function : integer; cdecl;
  TADL_OVERDRIVE5_TEMPERATURE_GET = function (iAdapterIndex, iThermalControllerIndex : integer; var lpTemperature : ADLTemperature) : integer; cdecl;
  TADL_OVERDRIVE5_FANSPEED_GET = function (iAdapterIndex, iThermalControllerIndex: integer; var lpFanSpeedValue: ADLFanSpeedValue): integer; cdecl;
  TADL_ADAPTER_NUMBEROFADAPTERS_GET = function (var lpNumAdapters: integer): integer; cdecl;
  TADL_ADAPTER_ACTIVE_GET = function(iAdapterIndex: integer; var lpStatus: Integer): Integer; cdecl;
  TADL_ADAPTER_ADAPTERINFO_GET = function(AInfo : Pointer; iInputSize: Integer): integer; cdecl;{stdcall;}

以这种方式创建变量:

var
  ADL_Overdrive5_Temperature_Get : TADL_OVERDRIVE5_TEMPERATURE_GET;
  ADL_Adapter_NumberOfAdapters_Get : TADL_ADAPTER_NUMBEROFADAPTERS_GET;
  ADL_Adapter_Active_Get : TADL_ADAPTER_ACTIVE_GET;
  ADL_Adapter_AdapterInfo_Get : TADL_ADAPTER_ADAPTERINFO_GET;
  ADL_Overdrive5_FanSpeed_Get : TADL_OVERDRIVE5_FANSPEED_GET;

  temperature : ADLTemperature;
  fanspeed : ADLFanSpeedValue;
  numGFX, numActiveGFX : Integer;
  GFXActive : Integer;
  x, size : integer;

  ADL_Info : AdapterInfo;
  ADL_PInfo : LPAdapterInfo;

  ADL_AInfo : Array of AdapterInfo;

  ADL_Result : Integer;
  ActiveAdapters : Array of Integer;
  Addr : Pointer;
  strPresent : String;

以这种方式链接到外部函数:

ADL_Adapter_NumberOfAdapters_Get := GetProcAddress(hDLL, 'ADL_Adapter_NumberOfAdapters_Get');
    ADL_Overdrive5_Temperature_Get := GetProcAddress(hDLL, 'ADL_Overdrive5_Temperature_Get');
    ADL_Adapter_Active_Get := GetProcAddress(hDLL, 'ADL_Adapter_Active_Get');
    ADL_Adapter_AdapterInfo_Get := GetProcAddress(hDLL, 'ADL_Adapter_AdapterInfo_Get');
    ADL_Overdrive5_Fanspeed_Get := GetProcAddress(hDLL, 'ADL_Overdrive5_FanSpeed_Get');

然后我尝试将数据放入数组和内存缓冲区。两者都返回完全相同的数据,但它无效。请注意,其他函数正在运行或返回有效错误,例如“驱动程序不支持”。

数组:

if Assigned(ADL_Adapter_AdapterInfo_Get) then
    begin
      //*** Array (delphi way)
      Setlength(ADL_AInfo, numGFX);
      Addr := ADL_AInfo;
      size := sizeof(AdapterInfo)*numGFX;

      try
        ADL_Result := ADL_Adapter_AdapterInfo_Get(Addr, size);
        If ADL_Result = ADL_OK then
        begin
          for x := 0 to numGFX-1 do
            begin
              //using a delphi array
              Memo1.Lines.Add('Vender ID for Adapter Index '+IntToStr(ADL_AInfo[x].iAdapterIndex)+' is '+IntToStr(ADL_AInfo[x].iVendorID));
              Memo1.Lines.Add('Device Number for Adapter Index '+IntToStr(ADL_AInfo[x].iAdapterIndex)+' is '+IntToStr(ADL_AInfo[x].iDeviceNumber));
              Memo1.Lines.Add('Adatper Name for Adapter Index '+IntToStr(ADL_AInfo[x].iAdapterIndex)+' is '+ADL_AInfo[x].strAdapterName);
              Memo1.Lines.Add('Display Name for Adapter Index '+IntToStr(ADL_AInfo[x].iAdapterIndex)+' is '+ADL_aInfo[x].strDisplayName);
              if ADL_AInfo[x].iPresent = 0 then strPresent := 'not present' else strPresent := 'present';
              Memo1.Lines.Add('Adapter Index '+IntToStr(ADL_AInfo[x].iAdapterIndex)+' is '+strPresent);
            end;
        end
        else
          Memo1.Lines.Add('Error : '+IntToStr(ADL_Result));
      finally
      end;
    end;

内存缓冲区:

if Assigned(ADL_Adapter_AdapterInfo_Get) then
begin
  //*** Pointer (c lookalike)
  size := sizeof(AdapterInfo)*numGFX;
  //GetMem(ADL_PInfo, size);
  ADL_PInfo := AllocMem(sizeof(AdapterInfo) * numGFX);


  try
    ADL_Result := ADL_Adapter_AdapterInfo_Get(ADL_PInfo, size);
    If ADL_Result = ADL_OK then
    begin
      for x := 0 to numGFX-1 do
        begin
          //using getmem with a pointer to a record
          Memo1.Lines.Add('Vender ID for Adapter Index '+IntToStr(ADL_PInfo.iAdapterIndex)+' is '+IntToStr(ADL_PInfo.iVendorID));
          Memo1.Lines.Add('Device Number for Adapter Index '+IntToStr(ADL_PInfo.iAdapterIndex)+' is '+IntToStr(ADL_PInfo.iDeviceNumber));
          Memo1.Lines.Add('Adatper Name for Adapter Index '+IntToStr(ADL_PInfo.iAdapterIndex)+' is '+ADL_PInfo.strAdapterName);
          Memo1.Lines.Add('Display Name for Adapter Index '+IntToStr(ADL_PInfo.iAdapterIndex)+' is '+ADL_PInfo.strDisplayName);
          if ADL_PInfo.iPresent = 0 then strPresent := 'not present' else strPresent := 'present';
          Memo1.Lines.Add('Adapter Index '+IntToStr(ADL_PInfo.iAdapterIndex)+' is '+strPresent);

          inc(ADL_Pinfo);
        end;
    end
    else
      Memo1.Lines.Add('Error : '+IntToStr(ADL_Result));

  finally

   // ZeroMemory(ADL_PInfo, size);
  end;
end;

【问题讨论】:

  • 首先将Char 替换为AnsiChar,正如链接问题中的评论所暗示的那样。
  • 另外,您的某些数组似乎是一个字符太长。 array [0..MAX_PATH]MAX_PATH+1 元素。
  • 基本上没有帮助,因为您发布了巨大的代码墙,但只有 Delphi 方面。您没有发布 C++ 代码,我们如何判断翻译是否准确?
  • 将 C++ 的墙翻译成帕斯卡的墙也不是真正的话题。
  • Serg 和 David 的组合修复了它。将 PRAXIS 文件更改为 MAX_PATH-1,将 Char 更改为 AnsiChar,我上面的代码的两个版本都运行良好。我应该看到这个......对于任何试图做同样的人我希望这个线程会有所帮助。谢谢大家!

标签: delphi delphi-xe2


【解决方案1】:

解决方案很简单。

  1. 下载 PRAXIS 库
  2. 在文件“adl_structures.pas”中查找所有 Char 实例并将它们更改为 AnsiChar
  3. 在同一文件中,查找“[0..MAX_PATH]”的所有实例并将它们更改为“[0..MAX_PATH-1]”

上面用于获取 DLL 中函数的指针并提取数据的代码是有效的并且工作正常

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 2021-11-17
    相关资源
    最近更新 更多