Sign in to follow this  
Followers 0
Don N

Passing By Reference Within A Dll Call

15 posts in this topic

#1 ·  Posted (edited)

This is the function in the Dll that i need to use

beInitStream( PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream  )

it uses pass by reference, how can i send my varables so that they are passed by reference and their values are returned to the program. The function itself jsut returns error or success.

here is my code so far, the problem results when i try to call this function. the Dll is lame_enc.dll availabe online

#include <file.au3>

$file = "testcase.wav"

$result = DllCall( "lame_enc.dll", "str", "BE_CONFIG", "str", "BE_CONFIG_LAME", "int", 1, "int", 331, "int", 44100, "int", 0, "string", "BE_MP3_MODE_JSTEREO", "int", 128, "str", "LQP_R3MIX", "str", "MPEG1", "int", 0, "int", 0, "string", "TRUE", "str", "TRUE", "int", 320, "str", "TRUE", "str", "TRUE", "str", "TRUE", "str", "TRUE", "str", "TRUE", "int", 5, "str", "TRUE", "str", "LQP_PHONE" )
            
Dim $beConfig
Dim $dwSamples
Dim $dwMP3Buffer
Dim $hbeStream

        
$err = DllCall( "lame_enc.dll", "str", "beInitStream", "PBE_CONFIG", $beConfig, "PDWORD", $dwSamples, "PDWORD", $dwMP3Buffer, "PHBE_STREAM", $hbeStream)
                
Dim $pMP3Buffer = $dwMP3Buffer
Dim $pWAVBuffer = $dwSamples
Dim $dwRead = 0
Dim $dwWrite = 0
Dim $dwDone = 0
Dim $dwFileSize = 0

MsgBox( 0, "", $dwSamples )

$dwFileSize = FileGetSize( $file )

While $dwDone <> $dwFileSize
    
    $dwRead = FileRead( $file, $dwSamples )
    
    $err = DllCall( "lame_enc.dll", "str", "beEncodeChunk", "HBE_STREAM", $hbeStream, "DWORD", dwRead, "PSHORT", $pWAVBuffer, "PBYTE", $pMP3Buffer, "PDWORD", $dwWrite )
    
    If $err <> 0 Then
        MsgBox( 0, "", "This is never good" )
        $dwDone = $dwFileSize
    EndIf
    
    $dwDone = $dwDone + 16 * $dwRead
    
    ToolTip( 100 * $dwDone / $dwFileSize )
    
    Sleep(1000)
WEnd
Edited by Don N

_____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper

Share this post


Link to post
Share on other sites



You might want to take a look at this link: http://www.autoitscript.com/forum/index.php?showtopic=7072

And though I'm not entirely familiar with it, you would probably need to look at DLLStructCreate()


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

thank you smoke_n, not very familiar w/dll usage yet...dllstruct is what i need, hope i can get it workin :)


_____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper

Share this post


Link to post
Share on other sites

ByReference is the same as passing a pointer. But you should conform to the calling convention used by the function in the dll. So you can't pass byReference to a function in a dll expecting a ByVal passed value (It could work but you should expect unexpected results).

The help file page for DllStructCreate indicates that a "ptr" definition will create a pointer reference to you variable.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

$return = beInitStream( PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream )

$return[0] = function return

$return[1] = pbeConfig

2 = dwSamples

... so on

maby it helps you maby it doesnt.

Edited by w0uter

My UDF's:;mem stuff_Mem;ftp stuff_FTP ( OLD );inet stuff_INetGetSource ( OLD )_INetGetImage _INetBrowse ( Collection )_EncodeUrl_NetStat_Google;random stuff_iPixelSearch_DiceRoll

Share this post


Link to post
Share on other sites

the dll call does not return an array, err is simply the success or failuer indicator returned by the function. Im looking into DllStructCreate but has anyone else done anything like this before?

Thanks for you help.


_____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper

Share this post


Link to post
Share on other sites

omg read the manual please. :)

lol thanks :(

i read the helpfile before starting this, i think i wasnt clear in my previous post or im doing somethign else wrong. I meant DllCall does not return an array and @error is not set to one which means the function call worked but i get errors when trying to access $err[0 or any other subscript].

mp3 converter.au3 (27) : ==> Subscript used with non-Array variable.:

$beConfig = $err[1]

$beConfig = $err^ ERROR

Im getting closer now using dllstructcreate(). Thanks.


_____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper

Share this post


Link to post
Share on other sites

lol thanks :)

i read the helpfile before starting this, i think i wasnt clear in my previous post or im doing somethign else wrong. I meant DllCall does not return an array and @error is not set to one which means the function call worked but i get errors when trying to access $err[0 or any other subscript].

mp3 converter.au3 (27) : ==> Subscript used with non-Array variable.:

$beConfig = $err[1]

$beConfig = $err^ ERROR

Im getting closer now using dllstructcreate(). Thanks.

If IsArray($err) Then

;Rest here

EndIf


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

ByReference is the same as passing a pointer. But you should conform to the calling convention used by the function in the dll. So you can't pass byReference to a function in a dll expecting a ByVal passed value (It could work but you should expect unexpected results).

The help file page for DllStructCreate indicates that a "ptr" definition will create a pointer reference to you variable.

A pointer and a reference are not the same thing. C doesn't support references and since most DLLs use C linkage, they either support "by-value" or "pointer" types.

Share this post


Link to post
Share on other sites

A pointer and a reference are not the same thing. C doesn't support references and since most DLLs use C linkage, they either support "by-value" or "pointer" types.

Since you are so picky about it would you pleace explaine how By Reference is implemented in the languages using them?

Share this post


Link to post
Share on other sites

Since you are so picky about it would you pleace explaine how By Reference is implemented in the languages using them?

What kind of request is that? How should I know how they are implemented? Why should I care about how they are implemented? All I should be worried about are the semantics of using them. Not only that, any half-decent literature on a language will tell you that the actual implementation of a reference is irrelevant. For example, typically in C++ a reference is only syntactically different from using pointers since both will end up using the address of the object. However, it is possible to implement references in a completely different manner than how pointers work in C++.

Don't call it picky when I correct a blatant incorrect use of terminology. As stated previously, C does not support references. Calling a pointer a reference is flat out wrong. If it were a reference, the actual object would be passed to the function. C does not support that, it only supports passing by-value (copy) or by-address (pointer). Passing by-reference (the object itself) is something completely different and is only available in C++, anyway. Even in C++, it may or may not be implemented the same way as pointers.

Share this post


Link to post
Share on other sites

What kind of request is that? How should I know how they are implemented? Why should I care about how they are implemented? All I should be worried about are the semantics of using them. Not only that, any half-decent literature on a language will tell you that the actual implementation of a reference is irrelevant. For example, typically in C++ a reference is only syntactically different from using pointers since both will end up using the address of the object. However, it is possible to implement references in a completely different manner than how pointers work in C++.

Exactly my point. When calling a function in a dll you are dealing with dll calling conventions and you can consider an argument expected to be a pointer, by the dll, as a call by reference. That is you should expect the value (or content) to have changed when the call returns.

I made the question because I belive you have some knowledge of AutoIt internals. So your opinion of how to think when talking about "by reference" would be reflected by that. My understanding is reflected by literature in C/C++, VB6 TCL/TK and some perl.

Don't call it picky when I correct a blatant incorrect use of terminology.

I actually think "picky" came out a bit wrong, so I am sorry about that. But I really don't think I have used the terminology wrong either. Finding references in the literature supporting this view, or understanding if you like, is to easy.

As stated previously, C does not support references. Calling a pointer a reference is flat out wrong. If it were a reference, the actual object would be passed to the function. C does not support that, it only supports passing by-value (copy) or by-address (pointer). Passing by-reference (the object itself) is something completely different and is only available in C++, anyway. Even in C++, it may or may not be implemented the same way as pointers.

I know that passing a string in VB6 ByRef involves passing a pointer. You do not get the MemCpy calls you would get if you did the call ByVal.

The AutoIt help file indicates that passing a array ByRef uses a pointer.

Obviously a compiler or interpreter could wrap code around a variable passed ByRef (I suppose AutoIt does) to make sure nothing evil happens (handle errors) but at the end ByRef is another name for a pointer.

Anyhow that is how I understand it at the moment.

Share this post


Link to post
Share on other sites

Exactly my point. When calling a function in a dll you are dealing with dll calling conventions and you can consider an argument expected to be a pointer, by the dll, as a call by reference. That is you should expect the value (or content) to have changed when the call returns.

Not usually. Most of the time, DLLs modify an argument via a pointer-to-pointer (**object) and not just through a pointer. For example, strings are passed as pointers but you don't expect functions to modify your string when you pass it that way, do you?

I made the question because I belive you have some knowledge of AutoIt internals. So your opinion of how to think when talking about "by reference" would be reflected by that. My understanding is reflected by literature in C/C++, VB6 TCL/TK and some perl.

No, my opinion is reflected in my knowledge of C++.

I actually think "picky" came out a bit wrong, so I am sorry about that. But I really don't think I have used the terminology wrong either. Finding references in the literature supporting this view, or understanding if you like, is to easy.

The problem here stems from two things. The first thing is that "reference" has a generic definition where you merely mean that in some way the original object is modified. The second definition is relevant to C++ where there is an actual reference operator present in the language. I dislike and disagree with the use of the term "reference" to describe pointers in C\C++ since there really is a tangible "reference" construct in C++. Since C++ is easily mixed with C, calling pointers references is confusing.

I know that passing a string in VB6 ByRef involves passing a pointer. You do not get the MemCpy calls you would get if you did the call ByVal.

So? That's an implementation detail. I don't care if it's carried on the back of a camel through 30 miles of desert. As long as it behaves like it's supposed to, I have no problem.

The AutoIt help file indicates that passing a array ByRef uses a pointer.

Obviously a compiler or interpreter could wrap code around a variable passed ByRef (I suppose AutoIt does) to make sure nothing evil happens (handle errors) but at the end ByRef is another name for a pointer.

Anyhow that is how I understand it at the moment.

That's really not even close. I also don't see any indication that AutoIt uses a pointer to do ByRef from the help file. And lastly, I don't see what the implementation of ByRef matters at all. If I wanted to sit down today and completely rewrite AutoIt's internal variable handling (including ByRef), I could and as long as it was done better than the current implementation, it would like be in a future version of AutoIt with hopefully no user-visible changes.

You're far too interested in implementation details. You're also using generic terminology where specific terminology would be much clearer; if something is a pointer, call it a pointer, not a reference.

Share this post


Link to post
Share on other sites

You guys are right. I am using pointers now adn am making progress on this. Sorry to set off such a debate, play nice :) Thanks for you help and clarification.


_____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper

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