brisesel Posted May 28, 2009 Share Posted May 28, 2009 (edited) Hi, I'm trying to use the ID3v2 Library :http://www.3delite.hu/..../id3v2library.htmlIt's an id3v2 tag editing library that supports the stdcall calling convention. (I know there is an UDF able to tag mp3 without a dll, but a little more restricted).I have little experience manipulating the DllCall function.Here is the script :local $dll=DllOpen ( "ID3v2Library.dll" ) ;~ # ID3v1_Create(): Pointer; stdcall; $tagpointer=DllCall($dll,"ptr","ID3v2_Create") ConsoleWrite ("ID3v2_Create " &@error &@CR) ; returns 0 ;~ # ID3v2_Load(Tag: Pointer; FileName: PChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Load","ptr",$tagpointer,"str","input.mp3" ) ; <--- crash ! ConsoleWrite ("ID3v2_Load " &@error &@CR) ;~ Set Title ; ID3v2_SetAsciiText(Tag: Pointer; FrameName, Text: PChar): Boolean; stdcall; DllCall($dld,"byte","ID3v2_SetAsciiText","ptr",$tagpointer,"str",'TIT2', "str","Some title") ConsoleWrite ("ID3v2_SetAsciiText " &@error &@CR) ;~ # ID3v2_Free(Tag: Pointer): Boolean; stdcall; DllCall($dld,"byte","ID3v2_Free","ptr",DllStructGetData ($struct_fichier,1) ) MsgBox(0,"ID3v2_Free" ,@error &@CR) DllClose($dll)It crashs with the second call. Did I use "ptr" the right way ?In comment, the Delphi function syntax.Here is the library usage example. I didn't translate InitID3v2Library* because it just seems to load the dll (but I never learnt delphi...)CODEUses ID3v2LibraryDefs;//* Should be in FormCreate()InitID3v2Library;ID3v2Tag := ID3v2_Create;ID3v2_Load(ID3v2Tag, FileName);//* Do whatever you want here...ID3v2_Save(ID3v2Tag, FileName);ID3v2_Free(ID3v2Tag);//* Should be in FormDestroy()FreeID3v2Library; Edited May 29, 2009 by brisesel Link to comment Share on other sites More sharing options...
brisesel Posted May 28, 2009 Author Share Posted May 28, 2009 (edited) ok... I'm on the good way, the second call crashs because I misunderstood the syntax, it needs absolute pathway... local $dll=DllOpen ( "ID3v2Library.dll" ) ;~ # ID3v1_Create(): Pointer; stdcall; $tagpointer=DllCall($dll,"ptr","ID3v2_Create") ConsoleWrite ("ID3v2_Create " &@error &@CR) ;~ # ID3v2_Load(Tag: Pointer; FileName: PChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Load","ptr",$tagpointer,"str",'"'&@ScriptDir&'\input.mp3"' ) ConsoleWrite ("ID3v2_Load " &@error &@CR) ;~ Set Title ; ID3v2_SetAsciiText(Tag: Pointer; FrameName, Text: PChar): Boolean; stdcall; $structchar=DllStructCreate("char[60]") DllStructSetData($structchar,1,"Some title") DllCall($dll,"byte","ID3v2_SetAsciiText","ptr",$tagpointer,"str","TIT2", "ptr",DllStructGetPtr($structchar,1)) ; crashs again.. ConsoleWrite ("ID3v2_SetAsciiText " &@error &@CR) ;~ # ID3v2_Free(Tag: Pointer): Boolean; stdcall; DllCall($dld,"byte","ID3v2_Free","ptr",DllStructGetData ($struct_fichier,1) ) MsgBox(0,"ID3v2_Free" ,@error &@CR) DllClose($dll) This time it the third call which crashes : Is anything incorrect in my autoit syntax ? By the way, I don't kown in autoit dllcall, it's the same thing to use : "str", "a string" and to use DllStructCreate("char[60]"), then to pass a pointer using "ptr", DllStructGetPtr ? Edited May 28, 2009 by brisesel Link to comment Share on other sites More sharing options...
martin Posted May 28, 2009 Share Posted May 28, 2009 (edited) ok... I'm on the good way, the second call crashs because I misunderstood the syntax, it needs absolute pathway... local $dll=DllOpen ( "ID3v2Library.dll" ) ;~ # ID3v1_Create(): Pointer; stdcall; $tagpointer=DllCall($dll,"ptr","ID3v2_Create") ConsoleWrite ("ID3v2_Create " &@error &@CR) ;~ # ID3v2_Load(Tag: Pointer; FileName: PChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Load","ptr",$tagpointer,"str",'"'&@ScriptDir&'\input.mp3"' ) ConsoleWrite ("ID3v2_Load " &@error &@CR) ;~ Set Title ; ID3v2_SetAsciiText(Tag: Pointer; FrameName, Text: PChar): Boolean; stdcall; $structchar=DllStructCreate("char[60]") DllStructSetData($structchar,1,"Some title") DllCall($dll,"byte","ID3v2_SetAsciiText","ptr",$tagpointer,"str","TIT2", "ptr",DllStructGetPtr($structchar,1)) ; crashs again.. ConsoleWrite ("ID3v2_SetAsciiText " &@error &@CR) ;~ # ID3v2_Free(Tag: Pointer): Boolean; stdcall; DllCall($dld,"byte","ID3v2_Free","ptr",DllStructGetData ($struct_fichier,1) ) MsgBox(0,"ID3v2_Free" ,@error &@CR) DllClose($dll) This time it the third call which crashes : Is anything incorrect in my autoit syntax ? By the way, I don't kown in autoit dllcall, it's the same thing to use : "str", "a string" and to use DllStructCreate("char[60]"), then to pass a pointer using "ptr", DllStructGetPtr ?Using "str","some string" should be ok, but I think the way you passed it here is wrong DllCall($dll,"int","ID3v2_Load","ptr",$tagpointer,"str",'"'&@ScriptDir&'\input.mp3"' ) I think it should be DllCall($dll,"int","ID3v2_Load","ptr",$tagpointer,"str",@ScriptDir & '\input.mp3' ) I can't comment on the way you've made the dllcalls otherwise because I have no knowledge of the dll you are calling or where to find the information for it. EDIT:spelling Edited May 28, 2009 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
brisesel Posted May 28, 2009 Author Share Posted May 28, 2009 reading the delphi source, your modification is right... But it makes ID3v2_Load crashing again. I think i will forget this dll. Anyway, thanks you. Link to comment Share on other sites More sharing options...
picaxe Posted May 28, 2009 Share Posted May 28, 2009 Maybe this udf (no dll required) Link to comment Share on other sites More sharing options...
trancexx Posted May 28, 2009 Share Posted May 28, 2009 DllCall() returns an array. You need to do this: $tagpointer=DllCall($dll,"ptr","ID3v2_Create") ; check errors... $tagpointer = $tagpointer[0] ... ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
brisesel Posted May 28, 2009 Author Share Posted May 28, 2009 (edited) >>>picaxe Thanks, but in last ressort... this is a fight between me an this dll (and by the way this dll offers much more implementation) >>>trancexx In fact, dllcall crashes before returning anything, so... In fact, the main trouble is probably the type conversion from delphi : ID3v2_Load(ID3v2Tag, PChar(Edit1.Text)); in this delphi code, ID3v2Tag is a pointer (the void pointer in c, "ptr" in autoit) PChar() returns a pointer to the string in argument (like char *p in c) (there is an explanation of delphi types there at the page bottom) I tried to translate this in autoit like this : local $dll=DllOpen ( "ID3v2Library.dll" ) $struc_ptr=DllStructCreate("ptr") DllStructSetData($struc_ptr,1,DllCall($dll,"ptr","ID3v2_Create") ) ConsoleWrite ("ID3v2_Create " &@error &@CR) ;~ # ID3v2_Load(Tag: Pointer; FileName: PChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Load","ptr",DllStructGetData($struc_ptr,1),"str","input.mp3" ) ; <--- crash (yeah, in fact relative path should also works) ConsoleWrite ("ID3v2_Load " &@error &@CR) ;< ---never arrives thereoÝ÷ Ø9e ©ejëh×6"str", "some string" works (passes a pointer to the first char of the string), because only when I change "input.mp3" to something that don't exist, there is no execution error (all @error set to 0)(and no result of course...) (and the dll is not buggy because there is an delphi compiled exe working in example...) So, I actually think that something may be wrong in the way I tried to implement the delphi pointer, or the way I pass the pointer to ID3v2_Load. If you find what it is.... EDIT : misspelling Edited May 28, 2009 by brisesel Link to comment Share on other sites More sharing options...
ProgAndy Posted May 28, 2009 Share Posted May 28, 2009 (edited) For me, this works: local $dll=DllOpen ( "ID3v2Library.dll" ) ;~ # ID3v1_Create(): Pointer; stdcall; $tagpointer=DllCall($dll,"ptr","ID3v2_Create") $tagpointer = $tagpointer[0] MsgBox(0, '', $tagpointer) ;# ID3v2_Load(Tag: Pointer; FileName: PChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Load","ptr",$tagpointer,"str", "D:\Music\A_File.mp3" ) ;~ ConsoleWrite ("ID3v2_Load " &@error &@CR) ;Set Title ; ID3v2_SetAsciiText(Tag: Pointer; FrameName, Text: PChar): Boolean; stdcall; DllCall($dll,"int","ID3v2_SetAsciiText","ptr",$tagpointer,"str","TIT2", "str","This is a Testtitle") ConsoleWrite ("ID3v2_SetAsciiText " &@error &@CR) ; ID3v2_Save(Tag: Pointer; FileName: PANSIChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Save","ptr",$tagpointer,"str", "D:\Music\A_File.mp3" ) ;~ # ID3v2_Free(Tag: Pointer): Boolean; stdcall; DllCall($dll,"int","ID3v2_Free","ptr",$tagpointer ) Edited May 28, 2009 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
martin Posted May 28, 2009 Share Posted May 28, 2009 (edited) >>>picaxe Thanks, but in last ressort... this is a fight between me an this dll (and by the way this dll offers much more implementation) >>>trancexx In fact, dllcall crashes before returning anything, so... In fact, the main trouble is probably the type conversion from delphi : in this delphi code, ID3v2Tag is a pointer (the void pointer in c, "ptr" in autoit) PChar() returns a pointer to the string in argument (like char *p in c) (there is an explanation of delphi types there at the page bottom) I tried to translate this in autoit like this : local $dll=DllOpen ( "ID3v2Library.dll" ) $struc_ptr=DllStructCreate("ptr") DllStructSetData($struc_ptr,1,DllCall($dll,"ptr","ID3v2_Create") ) ConsoleWrite ("ID3v2_Create " &@error &@CR) ;~ # ID3v2_Load(Tag: Pointer; FileName: PChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Load","ptr",DllStructGetData($struc_ptr,1),"str","input.mp3" ) ; <--- crash (yeah, in fact relative path should also works) ConsoleWrite ("ID3v2_Load " &@error &@CR) ;< ---never arrives thereoÝ÷ Ø9e ©ejëh×6"str", "some string" works (passes a pointer to the first char of the string), because only when I change "input.mp3" to something that don't exist, there is no execution error (all @error set to 0)(and no result of course...) (and the dll is not buggy because there is an delphi compiled exe working in example...) So, I actually think that something may be wrong in the way I tried to implement the delphi pointer, or the way I pass the pointer to ID3v2_Load. If you find what it is.... EDIT : misspelling I'm a bit confused by now and I'm not sure what version you have tried etc. Trancexx's note bout the dll returns looks like the main step forward to me but I don't see that you've applied that. What happens if you run this, and if there is a crash where does it occur? local $dll=DllOpen ( "ID3v2Library.dll" ) ;~ # ID3v1_Create(): Pointer; stdcall; $tagpointer=DllCall($dll,"ptr","ID3v2_Create") $tagpointer = $tagpointer[0] ConsoleWrite ("ID3v2_Create " &@error &@CR); returns 0 ;~ # ID3v2_Load(Tag: Pointer; FileName: PChar): Integer; stdcall; DllCall($dll,"int","ID3v2_Load","ptr",$tagpointer,"str",@ScriptDir & "\input.mp3" ); <--- crash??? ! ConsoleWrite ("ID3v2_Load " &@error &@CR) ;~ Set Title; ID3v2_SetAsciiText(Tag: Pointer; FrameName, Text: PChar): Boolean; stdcall; DllCall($dld,"byte","ID3v2_SetAsciiText","ptr",$tagpointer,"str",'TIT2', "str","Some title") ConsoleWrite ("ID3v2_SetAsciiText " &@error &@CR) ;~ # ID3v2_Free(Tag: Pointer): Boolean; stdcall; DllCall($dld,"byte","ID3v2_Free","ptr",$tagpointer) MsgBox(0,"ID3v2_Free" ,@error &@CR) DllClose($dll) EDIT: probably a redundant post since Prog@ndy got in first. Edited May 28, 2009 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
brisesel Posted May 29, 2009 Author Share Posted May 29, 2009 $tagpointer = $tagpointer[0]Thanks you all, there is the error !I was tired and misunderstood DllCall return type (thought it returned directly the called function return value...) Link to comment Share on other sites More sharing options...
ProgAndy Posted May 29, 2009 Share Posted May 29, 2009 trancexx already stated in post #6 that DLLCall returns an array *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
Paixao Posted June 4, 2009 Share Posted June 4, 2009 Interesting Functions of this dll. Somebody knows how to get the tags. Is it : DllCall($dll,"int","ID3v2_GetAsciiText","ptr",$tagpointer,"str","TIT2") ??? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now