2015-01-01 1 views
0

Я знаю несколько оснований Delphi (на самом деле я использовал его в течение нескольких лет) ...Правильно вызывать внешнюю dll в Delphi?

Я нахожусь на стене с DLL (никогда не играю с этим).

Рассмотрим следующий пример:

unit Unit1; 

interface 

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

Type FT_Result = Integer; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 


var 
    Form1: TForm1; 
    FT_HANDLE : DWord = 0; 



implementation 

{$R *.dfm} 

function I2C_GetNumChannels(numChannels: dword):FT_Result; stdcall; external 'libmpsse.dll' name 'I2C_GetNumChannels'; 
function I2C_OpenChannel(index:dword;handle:pointer):FT_Result; stdcall; external 'libmpsse.dll' name 'I2C_OpenChannel'; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
numofchannels:dword; 
begin 
i2c_getnumchannels(numofchannels); 
showmessage(inttostr(numofchannels)); 
end; 

end. 

Мне нужно взаимодействовать с libmpsse.dll от FTDI для доступа к шине I2C устройства к порту USB.
Когда я звоню в функцию I2C_GetNumChannels, я получаю тонны AccessViolation ...

Я просто хочу знать, что не так с функцией dll?

Также I2C_GetNumChannels предполагается возвращает 2 значения ...

enter image description here

Из официального руководства API здесь ->http://www.ftdichip.com/Support/Documents/AppNotes/AN_177_User_Guide_For_LibMPSSE-I2C.pdf

Большое спасибо!

С уважением

+1

'numChannels' является указателем на' DWORD', а не 'DWORD'. Объявление вашей функции неверно. –

+0

Я скорректировал код соответственно ... спасибо! – ELCouz

ответ

3

Ваш перевод неверный. Это должно быть:

function I2C_GetNumChannels(out numChannels: Longword): FT_Result; 
    stdcall; external 'libmpsse.dll'; 

Функция, которую вы вызываете, принимает адрес 32-битного беззнакового целого. Ваш перевод передал 32-битное целое число без знака по значению.

Вы можете перевести импорт с помощью указателей, но для абонента это проще сделать, используя параметр var или out, как я уже сделал.

Я предполагаю, что вы правильно определили, что соглашение о вызове - stdcall. Вам нужно будет проверить файл заголовка, чтобы точно знать.

Вы должны проверить значение, возвращаемое вызовом функции, для ошибок. Это самая распространенная ошибка, которую люди делают при вызове внешних библиотек. Не игнорируйте возвращаемые значения. Проверьте наличие ошибок.

+0

Вы правы! Спасибо, сэр переключился на CDECL (stdcall создавал нарушение прав доступа) – ELCouz

+0

Функция I2C_GetNumChannels (из numChannels: Longword): FT_Result; cdecl; external 'libmpsse.dll'; это правильный ответ – ELCouz

+0

Это может быть правильно, но не использовать пробную версию и ошибку. Проверьте файл заголовка. –

Смежные вопросы