![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DLL для MS Access [Delphi, Windows]
Kukushka-Q © (2008-09-12 17:57:00)Есть простелькая задача, запихнуть некоторые аудио данные из MP3-файлов в базу MS Access. С помощью библиотеки KOLATL сделана простенькая DLL, которая запускается из MS Access. В результате получем падение MS Access либо в процессе обращения, либо при закрытии. Первое, что приходит в голову - некорректно передаются/отдаются параметры и выгружается DLL. В Delphi я совсем чайник, поэтому прошу помочь разобраться.
Тестовый пример:
Код DLL на Delphi:
library DLLKOLATL;
{$X+}
uses
ShareMem,
SysUtils,
KOL,
ATLCommon,
AudioMPEG;
{$R *.res}
function GetAudioInfo(const FN:PChar; var aBitrate:integer):wordbool;export;stdcall;
// вместо var пробовал out - эффект одинаковый
Var
FName:String;
mMPEGAudioInfo:TMPEGAudioInfo;
Begin
FName:=trim(string(FN));
mMPEGAudioInfo.Create;
// mMPEGAudioInfo.ResetData;
Result:=mMPEGAudioInfo.ReadFromFile(FName);
if Result then begin
aBitrate:=mMPEGAudioInfo.Bitrate;
end else begin
aBitrate:=0;
end;
mMPEGAudioInfo.Free;
//mMPEGAudioInfo.Destroy; - это почему-то валит Access сразу
end;
exports
GetAudioInfo;
begin
end.
Вызов в MS Access:
Declare Function GetAudioInfo Lib "DLLKOLATL.dll" (ByVal FName _
As String, ByRef maSampleRate As Long) As Boolean
Sub test_dll()
Dim ABitRate As Long
Dim FileName As String
ABitRate = 0
FileName = "D:\Test.mp3"
Debug.Print GetAudioInfo(FileName, ASampleRate)
Debug.Print ASampleRate
End Sub
Kukushka-Q (2008-09-13 02:02:00) [1]Спасибо. Заработало. Насколько я понял моя основная ошибка была в неправильном создании объекта и объявлении его типа. Надо было:
mMPEGAudioInfo: PAudioInfo;
...
mMPEGAudioInfo := NewAudioMPEG;
Дмитрий К (2008-09-12 23:11:00) [2]
library Project1;
uses
KOL,
ATLCommon,
AudioMPEG;
function GetAudioInfo(FN: PChar; var aBitrate: Integer): WordBool; export; stdcall;
var
FName: string;
mMPEGAudioInfo: PAudioInfo;
begin
FName := FN;
// MsgOK(FName);
// MsgOK(Int2Str(aBitRate));
mMPEGAudioInfo := NewAudioMPEG;
try
Result := mMPEGAudioInfo.ReadFromFile(FName);
if Result then
aBitrate := mMPEGAudioInfo.Bitrate
else
aBitrate := 0;
finally
mMPEGAudioInfo.Free;
end;
end;
exports
GetAudioInfo;
begin
end.
Kukushka-Q (2008-09-12 20:16:00) [3]Кажется что строка (т.е. в данном случае имя файла) как раз передается нормально (я же её как константу передаю и память должна сразу резервироваться в нужном объеме)... Access падает теперь при закрытии :(.
Замена stdcall на safecall к сожалению вызывает сообщение об ошибке: Bad DLL calling convension. Замена на variant заваливает MS Access сразу в момент обращения к DLL :(.
Блин, вроде всё должно быть элементарно, я уже голову сломал!
mdw (2008-09-12 19:18:00) [4]Могу ошибаться, давно было, но насколько помню, когда мы связывались с аксесом и VB, то использовали Safecall. А передаваемую стоку описывали как Variant (As String). Думаю, PChar и String в бейсике есть разные типы. Передавайте указатель на память, потом ее обрабатывайте как PChar. А сперва попробуйте корректно вызвать процедуру, ничего не возвращая...
Kukushka-Q (2008-09-12 18:01:00) [5]Маленькая корректировка:
Declare Function GetAudioInfo Lib "DLLKOLATL.dll" (ByVal FName _
As String, ByRef maSampleRate As Long) As Boolean
Sub test_dll()
Dim ABitRate As Long
Dim FileName As String
ABitRate = 0
FileName = "D:\Test.mp3"
Debug.Print GetAudioInfo(FileName, ABitRate)
Debug.Print ASampleRate
End Sub