Sign in to follow this  
Followers 0
brisesel

[solved] need some help to solve dllcall crash

12 posts in this topic

#1 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites



#2 ·  Posted (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 by brisesel

Share this post


Link to post
Share on other sites

#3 ·  Posted (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 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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Maybe this udf (no dll required)

Share this post


Link to post
Share on other sites

DllCall() returns an array. You need to do this:

$tagpointer=DllCall($dll,"ptr","ID3v2_Create") 
; check errors...

$tagpointer = $tagpointer[0]
...

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#7 ·  Posted (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 by brisesel

Share this post


Link to post
Share on other sites

#8 ·  Posted (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 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

Share this post


Link to post
Share on other sites

#9 ·  Posted (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 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.

Share this post


Link to post
Share on other sites

$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...)

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Interesting Functions of this dll. Somebody knows how to get the tags.

Is it :

DllCall($dll,"int","ID3v2_GetAsciiText","ptr",$tagpointer,"str","TIT2")

??? :D

Share this post


Link to post
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
Sign in to follow this  
Followers 0