Jump to content
jugador

Autoit variable to dot Net

Recommended Posts

Want to pass autoit variable to dot Net.

VARIANT Connect(
        [in] long ID, 
        [in] SAFEARRAY(VARIANT)* Strings, 
        [in, out] VARIANT_BOOL* newValues);

All function working properly where no need to pass any parameter.

If i do like this is not working.Its not giving any error but i am not getting output.

Local $o_id = 111
Local $i_args[3] = ["joe","mike","david"]
Local $i_bool = -1
OleX.Connect($o_id, $i_args, $i_bool)

In this post @LarsJ  already mention VB.NET variable to receive the array must be an array of objects. An AutoIt array is an array of variants.

I know about @LarsJ "Variants and Safearrays" and "Using C# and VB Code in AutoIt through .NET Framework"

But due to Zero knowledge in dll stuff. Cant figure out how to convert the above example to dot NET variable.

 

Share this post


Link to post
Share on other sites

You can pass the variables to C# code this way:

tst00.cs

using System;
class TestClass {
  public void PassVars( int o_id, object[] i_args, int i_bool ) {
    Console.WriteLine( "C# code:" );

    Console.WriteLine( "o_id = {0}", o_id );

    Console.WriteLine( "i_args[0] = {0}", i_args[0] );
    Console.WriteLine( "i_args[1] = {0}", i_args[1] );
    Console.WriteLine( "i_args[2] = {0}", i_args[2] );

    // Convert object to string
    string sStr = (string) i_args[0];
    Console.WriteLine( "sStr = {0}", sStr );

    Console.WriteLine( "i_bool = {0}", i_bool );

    // Convert variables so that they can be passed to the Connect method.

    // Execute the Connect method from within the C# code.
  }
}

tst00.au3

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

;#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include "DotNetAll.au3"

Example()

Func Example()
  Local $oNetCode = DotNet_LoadCScode( FileRead( "tst00.cs" ), "System.dll" )
  Local $oTestClass = DotNet_CreateObject( $oNetCode, "TestClass" )

  Local $o_id = 111
  Local $i_args[3] = ["joe","mike","david"]
  Local $i_bool = -1

  $oTestClass.PassVars( $o_id, $i_args, $i_bool )
EndFunc

Console output

C# code:
o_id = 111
i_args[0] = joe
i_args[1] = mike
i_args[2] = david
sStr = joe
i_bool = -1

 

Share this post


Link to post
Share on other sites

@LarsJ

I tried this way after posting but still getting no input.

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include "DotNetAll.au3"

Global $sDLL_path  = "..........\DataA.dll"

_Example()

Func _Example()
    Local $o_id = 111
    Local $i_args[3] = ["joe","mike","david"]
    Local $i_bool = -1  ;VT_Bool

    ;;----
    Local $oDllobj = DotNet_LoadAssembly($sDLL_path)
    MsgBox(0, "", "Load Dll: " & IsObj($oDllobj) & @CRLF)   ;;ok
    

    Local $OleX = DotNet_CreateObject($oDllobj, "Data.Server")
    MsgBox(0,"","Is Obj: " & IsObj($OleX) & @CRLF)      ;;ok
    ;;----

    Local $opulseRate = $OleX.PulseRate()
    MsgBox(0, "", "pulseRate: " & $opulseRate & @CRLF)  ;;ok

    ;;----
    Local $oValue = $OleX.Connect($o_id, $i_args, $i_bool)  ;; not getting any value
    MsgBox(0, "", "Value: " & $oValue & @CRLF)
    ;;----
EndFunc

This the software I am using so I know nothing about its internal coding stuff.

only this much....

VARIANT Connect(
        [in] long ID, 
        [in] SAFEARRAY(VARIANT)* Strings, 
        [in, out] VARIANT_BOOL* newValues);
        
long PulseRate();

void Disconnect([in] long ID);

 

Edited by jugador

Share this post


Link to post
Share on other sites

OleX.Connect($o_id, $i_args, $i_bool) does not work because $i_args is not properly converted to a safearray of variants and because $i_bool is not properly converted to a variant.

There are two ways to move forward. The easiest way is to drop all AutoIt code and then make the code work in pure C# code. And then you may not need the AutoIt code at all.

A more difficult way is to create a safearray and a variant in AutoIt code and then pass that data to C# code as pointers. But it's imperative to verify that the safearray and variant are correctly passed to the C# code (by printing data in the same way as in the C# code above).

Share this post


Link to post
Share on other sites

Thanks  @LarsJ  for helping out.
No C# knowledge so by default I have to take Autoit route.

Larsj how I convert this below example

;~~ to a safearray of variants
Local $i_args[3] = ["joe","mike","david"]

;~~ to a variant 
Local $i_bool = -1  ;VT_Bool

 

Edited by jugador

Share this post


Link to post
Share on other sites

The problem with using pure AutoIt code as in your code above is that it's not possible to verify the effects of COM conversions in the internal AutoIt code, and the effects of marshalling when a safearray and a variant is passed from unmanaged AutoIt code to managed C# code. You don't know if data has been passed correctly. This can only be verified in the C# code. Without C# code, the chances of the code working is as close to zero as possible at all.

To succeed with this code you will need to upgrade your lack of knowledge of C# code to a little bit of knowledge. Just enough to understand and write code as in post 2 above, which can be executed directly from AutoIt. However, there is the added complexity that you have to deal with safearrays and variants directly. In the documentation for the Connect method, isn't there an example of how to use the method in C# and how to create the required safearray and variant? If not then google. It should be possible to find examples showing how to create a safearray and a variant.

In AutoIt you create a 1D safearray of variants containing strings this way:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

;#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include "Variant.au3"
#include "SafeArray.au3"

Example()

Func Example()
  Local $i_args[3] = ["joe","mike","david"]
  Local $pSafeArray = ArrayOfStringsToSafeArrayOfVariantsOfBStrings( $i_args )
  ConsoleWrite( "$pSafeArray = " & $pSafeArray & @CRLF )
EndFunc

Func ArrayOfStringsToSafeArrayOfVariantsOfBStrings( ByRef $aArray )
  Local $tsaBound = DllStructCreate( $tagSAFEARRAYBOUND ), $pSafeArray, $pSafeArrayData, $iArray = UBound( $aArray ), $iPtrSize = @AutoItX64 ? 8 : 4
  DllStructSetData( $tsaBound, "cElements", $iArray )
  DllStructSetData( $tsaBound, "lLbound", 0 )
  $pSafeArray = SafeArrayCreate( $VT_BSTR, 1, $tsaBound )
  SafeArrayAccessData( $pSafeArray, $pSafeArrayData )
  For $i = 0 To $iArray - 1
    DllStructSetData( DllStructCreate( "ptr", $pSafeArrayData + $iPtrSize * $i ), 1, SysAllocString( $aArray[$i] ) )
  Next
  SafeArrayUnaccessData( $pSafeArray )
  Return $pSafeArray
EndFunc

You create a variant of type VT_BOOL this way:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

;#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include "Variant.au3"

Example()

Func Example()
  Local $tVariant = DllStructCreate( $tagVARIANT ), $pVariant = DllStructGetPtr( $tVariant )
  DllStructSetData( DllStructCreate( "word", $pVariant ), 1, $VT_BOOL )
  DllStructSetData( DllStructCreate( "short", $pVariant + 8 ), 1, -1 )
  ConsoleWrite( "$pVariant = " & $pVariant & @CRLF )
EndFunc

 

Share this post


Link to post
Share on other sites

@LarsJ

How to implement CallbackObject in Autoit

long ServerStart([in] IRTDUpdateEvent* CallbackObject);
interface IRTDUpdateEvent : IDispatch {
    HRESULT UpdateNotify();
    HRESULT HeartbeatInterval([out, retval] long* value);
    HRESULT Disconnect();
    };
Func _Example()
    ;;----
    Local $OleX = ObjCreate("Data.Server")
    MsgBox(0,"","Is Obj: " & IsObj($OleX))
    ;;----

    ;;simple this will not work
    ;;So, how I implement CallbackObject of IRTDUpdateEvent?
    Local $o_IRTDUpdate = $OleX.ServerStart(????)
EndFunc

 

Edited by jugador

Share this post


Link to post
Share on other sites

You can try to create an object with the ObjEvent() function and use this object as a parameter in the ServerStart() method.

It's usually easiest if you have some working code as a starting point. Especially if you are also able to run and debug the code. Then you can try to translate the code into AutoIt.

Share this post


Link to post
Share on other sites

I would not recommend translating this code into AutoIt. It'll be extremely time consuming. And there's no guarantee you can make it all work.

If you want to use the code, run it as pure .NET code.

Share this post


Link to post
Share on other sites

I thought using GUIRegisterMsg or ObjEvent or DllCallbackRegister it easy to implement ServerStart(IRTDUpdateEvent* callback) method.
Above post (stackoverflow link)... there a working AHK code except this callback function missing.
Anyway thanks for the help @LarsJ, I will drop the idea.

Edited by jugador

Share this post


Link to post
Share on other sites

No no no. These functions can only be used in relation to standard Windows code. Eg. The Windows API functions used to implement most official AutoIt UDFs (the include files) and internal AutoIt code. These functions cannot be used in relation to .NET code.

There is a fundamental difference between standard Windows code and .NET code. The differences may be compared to the differences on Windows and Linux operating systems.

But just as techniques exist to integrate Windows and Linux operating systems to some extent, so do techniques for integrating standard Windows code and .NET code. And these are such techniques that need to be used here.

In AutoIt, there are no internal functions to support the techniques, and the techniques are at a somewhat experimental level. To get an impression of the code in question, take a look at the code on the pages of this thread. It's not that easy.

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.

×
×
  • Create New...