Jump to content
IndianSage

DllCall to my dll function returning structure is not working.

Recommended Posts

I have create a function in FreeBasic like below:

Extern "Windows-MS"

    Type tA
        f1 As Integer
        f2 As Integer
    End Type

    Public Function _switchOrder(ByVal no1 As Integer, ByVal no2 As Integer) As tA Export
        Dim result As Integer

        Dim taa As  tA  

        taa.f1 = no2

        taa.f2 = no1

        Return taa

    End Function

End Extern

Caller AutoIt code is:

#include <MsgBoxConstants.au3>

Global Const $sTag_ftdi_version_info="struct; int no1a; int no2a; endstruct"

Local $aRet=DllCall("Math1.dll","Ptr","_switchOrder", "Int", 10, "Int", 30)
;MsgBox (0,"",@error & "-" & $aRet[0] & "-" & $aRet[1]& "-" & $aRet[2])

Local $t_ftdi_version_info=DllStructCreate($sTag_ftdi_version_info,$aRet[0])
MsgBox (0,"msg1=",@error & "---" & $aRet[0] & "-" & $aRet[1]& "-" & $aRet[2])

;Local $retData1 = DllStructGetData($t_ftdi_version_info,"",1)
Local $retData1 = DllStructGetData($t_ftdi_version_info,"no1a")
MsgBox (0,"msg2=",@error & "--" & $retData1)

;Local $retData1 = DllStructGetData($t_ftdi_version_info,"",2)
Local $retData1 = DllStructGetData($t_ftdi_version_info,"no2a")
MsgBox (0,"msg2=",@error & "--" & $retData1)

;ConsoleWrite(DllStructGetData($t_ftdi_version_info,"",2) & "--" & @error)
;ConsoleWrite(DllStructGetData($t_ftdi_version_info,"no2a") & @CRLF)
;ConsoleWrite(DllStructGetData($tversion_str,1) & @CRLF)

Getting error 2 for DllStructGetData or it give Close Application AutoIt popup message. 

Certainly DllCall is not returning pointer to the Structure in $aRet[0] hence issue.

Can someone help me fix this please?

Thanks in advance.

 

 

Share this post


Link to post
Share on other sites

Moved to the correct forum, as the Technical Discussion form very clearly states "DO not post general support questions here"


"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Share this post


Link to post
Share on other sites

Mr. JLogan,

Just be clear, was my this question supposed to be in General Support category?

Thanks for bearing with me till I get to understand the categories clearly.

Share this post


Link to post
Share on other sites

Hello I'm not a freebasic programmer but I think your structure will be free when the function ends. probably you need to use a global structure. I'm not sure if freebasic provide structure pointer or need to use a function like strptr or varptr like old vb6 or something like @Mystructure.  I think is not a good practices to return an structure from a library.  the correct way should be that you pass your structure's pointer an be filled/modify inside the library.

 

Saludos

Share this post


Link to post
Share on other sites

It seems @Danyfirex is right.

After some tests, it seems this one works :

Extern "Windows-MS"
    Type tA
        f1 As Integer
        f2 As Integer
    End Type
    
    Public Function addition(no1  As Integer, no2  As Integer, Byref v As tA Ptr) As Integer Export
        Dim o As tA
        Dim s As Integer
        o.f1 = no2
        o.f2 = no1
        *v = o
        Return 0
    End Function

End Extern
Local $ptr = DllStructCreate("int f1;int f2")

$aRet = DllCall('test.dll', 'int', 'addition', 'int', 10, 'int', 30, 'ptr*', DllStructGetPtr($ptr) )
ConsoleWrite( "F1=" & DllStructGetData($ptr, 'f1') & @LF & _
              "F2=" & DllStructGetData($ptr, 'f2') & @LF )

 

Edited by jguinch

Share this post


Link to post
Share on other sites

By the way I tried with Array too using ClassLibrary using Vb.net and C# both but it does not work. The other functions with VB.Net and C# returning Integers etc. worked fine.

I will try now with ByRef Array and modify them in ClassLibrary function as suggested by DanyFirex above and see if I get the data back. 

If it works fine my main purpose of returning multiple large number of items from classlibrary function is solved then in that case. 

I will revert after trying it out. Thanks in the meanwhile.

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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By IndianSage
      Hi,
      My AutoIt script is as folllows:
      ;use for calling function add2NosA in dll ;Local $vNo1 = 33 ;Local $vNo2 = 11 ;use for calling function sortNos in dll Local $vNo1 = [11,7,9] Local $vNo2 = [1,3,2] ; _ArrayDisplay($vNo1, "vNo1 display") ; _ArrayDisplay($vNo2, "vNo2 display") ;Local $hWnd = DllOpen("E:\CV-Dell-1\autoit3\myComObj1.dll") Local $hWnd = ObjCreate("myComObj1.clsMath") if (@error) Then MsgBox (0, "Error", "Error1 = " & @error) Exit EndIf ;function call method - DllCall with function name ;Local $aRes = DllCall($hWnd, "int", "addNosA", "int", $vNo1, "int", $vNo2) ;Local $aRes = DllCall($hWnd, "Ptr", "sortNos", "Array", $vNo1, "Array", $vNo2) ;function call method - $hWnd.<function name> ;Local $aRes = $hWnd.add2NosA($vNo1, $vNo2) ; this works fine with ObjCreate Local $aRes = $hWnd.sortNos($vNo1, $vNo2) if (@error) Then MsgBox (0, "Error", "Error2 = " & @error) DllClose($hWnd) Exit EndIf ;use appropriate msgbox ;MsgBox(0,"Result", "Result = " & $vNo1[0]) MsgBox(0,"Result", "Result = " & $aRes) _ArrayDisplay($vNo1, "vNo1 display") _ArrayDisplay($aRes , "aRes display") DllClose($hWnd) My VB.Net - ClassLibrary - Dll - COM obj is as follows - has 2 functions - add2NosA and sortNos:
      <ComClass(clsMath.ClassId, clsMath.InterfaceId, clsMath.EventsId)> Public Class clsMath Public Const ClassId As String = "3A42F85E-24C8-4BAA-91B5-AE56C4683C13" Public Const InterfaceId As String = "D99D7C79-2BA7-4A33-B7BC-9B7F19FDF828" Public Const EventsId As String = "CA128AC4-580C-4112-9EAD-8D1599E3F37A" Public Sub New() MyBase.New() End Sub Public Function add2NosA(ByVal no1 As Integer, ByVal no2 As Integer) As Integer Return (no1 + no2) End Function Public Sub sortNos(ByRef no1 As Array, ByRef no2 As Array) Array.Sort(no1) no2 = no1 End Sub End Class  Over all I tried various 8 options mentioned in the attached Excel file - with only 1 combination working.
      Overall could not make Array returned capture in AutoIt script. 
      Can someone help please?
      Thanks in  advance.
      Options-Tried-Matrix-Results.xlsx
    • By xYuri
      This simple dllcall gives me error 5, access denied,
      Func _WinAPI_VkKeyScan($__key) _WinAPI_SetLastError(0) $res = DllCall('User32.dll', 'SHORT', 'VkKeyScan', 'CHAR', $__key) _xConsole('res: '&$res) $_LastErr = _WinAPI_GetLastError() If $_LastErr <> 0 Then _xConsole('Err: {' & $_LastErr & '}> ' & _WinAPI_GetLastErrorMessage()) Return $res EndFunc Am i doing something wrong?
      Also tried VkKeyScanA and W
      Edit:
      I want to send `:` via PostMessage() WM_KEYDOWN
    • By Skysnake
      This is relevant
      From here https://stackoverflow.com/questions/3454315/is-it-possible-to-pin-a-dll-in-memory-to-prevent-unloading
      I use several UDFs on the Forum to do various things.  Those UDFs work very well.
      Effectively the UDFs are DLL wrappers, that make it possible to access DLL functions easily without the long hard slog of DLLCall() every time.
      However, I have now run into the issue that multiple UDF DLLCalls are slow. Not mind numbingly slow, but slow enough to become noticeable with a large of repeated function calls.
      So I was wondering, is it possible to "load a DLL into memory" and leave it there for the duration of my script's lifetime, avoid repeated DLL on-disk reads with a persistent in memory DLL?
      From Microsoft
      https://docs.microsoft.com/en-us/windows/desktop/dlls/about-dynamic-link-libraries
      Looks like what I want to do is: load-time dynamic linking,
      So next question, (a) how do I do this with AutoIt (b) How would this impact on standard AutoIt type DLL calls?
       
      The point is speed.  Is there a different approach?
      Or am I barking up the wrong tree?
      Skysnake
    • By supersonic
      Hi -
      Currently I'm playing around with Windows Credential Manager. I'm trying to access it with DllCall("advapi32.dll", ...) using the functions 'CredWriteW', 'CredReadW' and 'CredDeleteW'. All well. Another function I have to deal with is 'CredEnumerateW': https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credenumeratew/ .
      That's the test code I have so far:
      #include <Array.au3> #include <String.au3> Local $tCredentialsCount = DllStructCreate("DWORD;") Local $tPointerToArrayOfPointers = DllStructCreate("PTR;") ; Local $tPointerToArrayOfPointers = DllStructCreate(_StringRepeat("PTR;", 200)) ; ??? Local $aResult = DllCall("advapi32.dll", "BOOL", "CredEnumerateW", _ "WSTR", Null, "DWORD", 1, "DWORD", DllStructGetPtr($tCredentialsCount), "PTR", DllStructGetPtr($tPointerToArrayOfPointers)) If (Not @error) Then Local $iCredentialsCount = DllStructGetData($tCredentialsCount, 1) _ArrayDisplay($aResult, $iCredentialsCount) Local $hPointerToArrayOfPointers = DllStructGetData($tPointerToArrayOfPointers, 1) MsgBox(0, "$hPointerToArrayOfPointers", $hPointerToArrayOfPointers) ; Fails... For $i = 1 To 10 ; $iCredentialsCount MsgBox(0, $i & "___" & (($i * 2) - 1), DllStructGetData($tPointerToArrayOfPointers, ($i * 2) - 1)) Next $tCredentialsCount = 0 $tPointerToArrayOfPointers = 0 DllCall("advapi32.dll", "NONE", "CredFreeW", "PTR", $hPointerToArrayOfPointers) EndIf The DllCall seems to function properly - I get a valid count of credentials (on my computer ~ 133) and a pointer "to array of pointers".
      What is meant by "array of pointers"?
      Microsoft says: Pointer to an array of pointers to credentials. The returned credential is a single allocated block. Any pointers contained within the buffer are pointers to locations within this single allocated block.
      How to access these pointers... Contained within the buffer???
      Any information you can provide me would be greatly appreciated.
    • By bladem2003
      Hello,
      i need help to translate the c code to autoit .
      I don't understand the callback function.
       
      #include <windows.h> #include <stdio.h> // native IR Data by PAnsiChar typedef void CALLBACK CallBackPAnsiChar(char*, char*, char*, char*); typedef int (__stdcall *impInitPAnsiChar)(CallBackPAnsiChar); CALLBACK MyCallBackPAnsiChar(char* Protocol, char* Address, char* Command, char* Flags) { printf("\nIR Data received: Protocol: %s, Address: 0x%s, Command: 0x%s, Flags: 0x%s", Protocol, Address, Command, Flags); fflush(stdout); } int main(int argc, char **argv) { impInitPAnsiChar InitPAnsiChar = NULL; // Load DLL file HINSTANCE hinstLib = LoadLibrary(TEXT("USB_IR_Remote_Receiver.dll")); if (hinstLib == NULL) { printf("\nERROR: unable to load DLL\n"); return 1; } // Get function pointer InitPAnsiChar InitPAnsiChar = (impInitPAnsiChar)GetProcAddress(hinstLib, "InitPAnsiChar"); if (InitPAnsiChar == NULL) { printf("\nERROR: unable to find DLL function\n"); FreeLibrary(hinstLib); return 1; } if (InitPAnsiChar(*MyCallBackPAnsiChar)) { printf("\nInit DLL with InitPAnsiChar successfull"); } else { // Unload DLL file FreeLibrary(hinstLib); return 0; } while(1) { } //return 0; }  
×
×
  • Create New...