Jump to content

[solved] need some help to solve dllcall crash


Recommended Posts

Hi, I'm trying to use the ID3v2 Library :

http://www.3delite.hu/..../id3v2library.html

It'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...)

CODE
Uses 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 by brisesel
Link to comment
Share on other sites

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 by brisesel
Link to comment
Share on other sites

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 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

>>>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 by brisesel
Link to comment
Share on other sites

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 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

>>>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 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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...