Jump to content

3rd party DLL access difficulty


marekp
 Share

Go to solution Solved by Danyfirex,

Recommended Posts

You're not passing third parameter(&retError) 😅.  it's. "uint*",0

 

Saludos

 

 

Link to comment
Share on other sites

43 minutes ago, Danyfirex said:

You're not passing third parameter(&retError) 😅.  it's. "uint*",0

Well, that certainly fixed that problem! But if I remember my C++, it's a 'default argument' ( = Null) and so is optional? The plain text documentation for the DLL doesn't even mention it:

 

2.2.2. LMX_func_api_Select_PnPDevice
Performs the connection process of a selected device.

[Format]

UINT8  LMX_func_api_Select_PnPDevice (
    UINT32                   dwDevIndex,
    PLMX_CONNECT_DEVICE_INFO plmxPnpDevInfo
)
[Parameters]

UINT32 dwDevIndex
Index value indicating the location where the selected device's information is stored.

PLMX_CONNECT_DEVICE_INFO plmxPnpDevInfo
Pointer of LMX_CONNECT_DEVICE_INFO structure for storing information on devices that can be connected.

[Return values]

UINT8
LMX_BOOL_TRUE is returned when information on devices that can be connected is got successfully.

[Notes]
Information on devices that can be connected needs to be got using LMX_func_api_Get_PnPDeviceInfo before processing this API..

 

It's also odd that the earlier invocations of DllCall (and others) managed quite well without it (expected behaviour).

Anyway, thanks again.

 

Link to comment
Share on other sites

Yet another DllCall issue (sorry!)...

According to the reference for DllCall, the returned array should include the parameters passed by ref to the DLL function, but I'm getting a miss-match with...

Local $checkSS = 0
    Local $retError = 0
    Local $r = DllCall($hDll, "byte:cdecl", "LMX_func_api_SS_Get_Param", "uint*", $checkSS, "uint*", $retError)
    if @error Then Errorfatal("DllCall LMX_func_api_SS_Get_Param", @error)
    if $r[0] <> 1 then ErrorFatal("LMX_func_api_SS_Get_Param returned FALSE", @error)
    ConsoleWrite("Current shutter speed: " & Hex($checkSS, 8) & @CRLF)
    ConsoleWrite("   " & Hex($r[1], 8) & @CRLF)

... The console being:

Current shutter speed: 00000000
   800003E8

So the DllCall returns the expected value in the return array, but the value doesn't appear in $checkSS.

The DLL function prototype is...

UINT8 LMX_API LMX_func_api_SS_Get_Param(UINT32 *pulParam, UINT32 *retError = NULL);

Any hints as to what's going wrong?

Edited by marekp
Link to comment
Share on other sites

Hello.

Local $r = DllCall($hDll, "byte:cdecl", "LMX_func_api_SS_Get_Param", "uint*", 0, "uint*",0)
    if @error Then Errorfatal("DllCall LMX_func_api_SS_Get_Param", @error)
    if $r[0] <> 1 then ErrorFatal("LMX_func_api_SS_Get_Param returned FALSE", @error)
    Local $checkSS =$r[1]
    Local $retError = $r[2]
    ConsoleWrite("Current shutter speed: " & Hex($checkSS, 8) & @CRLF)
    ConsoleWrite("   " & Hex($retError, 8) & @CRLF)

Saludos

Edited by Danyfirex
Link to comment
Share on other sites

No it is not a bug.  It is simply the way DllCall works.  It returns an array containing the resulting parameters of the call.  The parameters passed to the function are not modified.

Link to comment
Share on other sites

57 minutes ago, Nine said:

No it is not a bug.  It is simply the way DllCall works.  It returns an array containing the resulting parameters of the call.  The parameters passed to the function are not modified.

... unless it's a structure? I didn't need to parse the return array in that case. It would be nice if the reference documentation made that distinction.

Link to comment
Share on other sites

I thought I was nearly there, but have tripped over one more problem.

I'm calling a DLL function that returns a large block of binary data (about 3,5MB). Prototype is...

UINT8 LMX_API LMX_func_api_Get_Object(UINT32 ObjectHandle,UINT8* lpStoreBufAdder,UINT32 StoreBufSize, UINT32 *retError = NULL);

My code tries to invoke this with...

    Local $str_LMX_func_api_Get_Object_Struct = "uint ObjectHandle;byte lpStoreBufAdder[" & $fsize & "];uint StoreBufSize;"
    Local $LfaGOS = DllStructCreate($str_LMX_func_api_Get_Object_Struct)
    if @error Then Errorfatal("DllStructCreate", @error)

    Local $r = DllStructSetData($LfaGOS, "ObjectHandle", $hObj)
    if @error Then Errorfatal("DllStructSetData", @error)
    Local $r = DllStructSetData($LfaGOS, "StoreBufSize", $fsize)
    if @error Then Errorfatal("DllStructSetData", @error)

    ConsoleWrite("Call..." & @crlf)
    Local $r = DllCall($hDll, "byte:cdecl", "LMX_func_api_Get_Object", "ptr", DllStructGetPtr($LfaGOS), "uint*", 0)
    if @error Then Errorfatal("DllCall LMX_func_api_Get_Object", @error)
    ConsoleWrite("   ... done" & @crlf)

... and all goes well till the DllCall function crashes.

Any hints?


 

Link to comment
Share on other sites

6 minutes ago, Danp2 said:

It appears that you are trying to include the parameters into your structure. That's not the way it works AFAIK.

I thought I had to do it that way otherwise there's no way of defining the size of the buffer (in bytes). I originally tried without the DllStruct stuff, e.g., 

Local $imageData[$fsize]

Local $r = DllCall($hDll, "byte:cdecl", "LMX_func_api_Get_Object", "uint", $hObj, "ptr", $imageData, "uint", $fsize, "uint*", $retError)

... but that crashed too and in retrospect I couldn't see how it would know the 'size' (bytes) since AutoIt variable are untyped. Using structs seemed the way round it.

 

Link to comment
Share on other sites

Is there another way (other than via structures) of getting a pointer to a memory buffer of a given size? I couldn't find anything obviously appropriate.

As for the size,  $fsize was the size I was given for the object via an earlier DLL function call, so it *should* be right. Making it twice as big didn't help.

Link to comment
Share on other sites

Post DLL API documentation(header declaration etc). It would be easier for us to help you. 

 

Saludos

 

Link to comment
Share on other sites

8 minutes ago, Danyfirex said:

Post DLL API documentation(header declaration etc). It would be easier for us to help you. 

I posted the DLL function prototype about 2 hours ago 😉 Perhaps I should have started a new thread?

Anyway, I've found something that works: I used a DllStruct only for the big buffer rather than for the full set of parameters:

Local $buffer = DllStructCreate("byte[" & $fsize & "]")
    Local $pBuffer = DllStructGetPtr($buffer)

    ConsoleWrite("Call..." & @crlf)
    Local $r = DllCall($hDll, "byte:cdecl", "LMX_func_api_Get_Object", "uint", $hObj, "ptr", $pBuffer, "uint", $fsize, "uint*", 0)
    if @error Then Errorfatal("DllCall LMX_func_api_Get_Object", @error)
    ConsoleWrite("   ... done" & @crlf)

... and this seemed to work better. Although I still don't understand why the original code caused a crash. It seemed 'legitimate'.

Thanks all!

Link to comment
Share on other sites

It crashed before. because you're missing some parameters I think.

Your last method is the correct method to go with. 

PD: stay in this thread is ok.

Saludos

 

Edited by Danyfirex
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...