Andreik

CUDA dll functions

6 posts in this topic

Does anyone tried with success to compile a dll with a function that use CUDA and then to call the function from AutoIt? Actually the compilation seems to be easy but it might be a little hard to call the function. Here is what I have:

cuda.cu

#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>


__global__ void cuda__add(int *a, int *b, int *c)
{
   *c = *a + *b;
}

extern "C" __declspec(dllexport) int Add(int a, int b)
{
  int c;
  int *dev_a,*dev_b,*dev_c;
  int size = sizeof(int);

  cudaMalloc((void**)&dev_a, size);
  cudaMalloc((void**)&dev_b, size);
  cudaMalloc((void**)&dev_c, size);

  cudaMemcpy(dev_a, &a,sizeof(int), cudaMemcpyHostToDevice);  
  cudaMemcpy(dev_b, &b,sizeof(int), cudaMemcpyHostToDevice);  

  cuda__add<<< 1,1 >>>(dev_a,dev_b,dev_c);
  cudaMemcpy(&c, dev_c,size, cudaMemcpyDeviceToHost);

  cudaFree(&dev_a);
  cudaFree(&dev_b);
  cudaFree(&dev_c);

  return c;
}

I am able to open the dll but the function is not visible somehow and I get error 3 when I call it from AutoIt.


When the words fail... music speaks

Share this post


Link to post
Share on other sites



Hello Andreik,:)

I use CUDA myself, but in a pure C++ environment (need for speed). However, I do have some experience in integrating my own dlls in AutoIt. First off, there's a mismatch between your function declaration and the actual definition (first has 2 parameters, second 3).

My next reaction would be to check capitalisation in the dll call, as these function names are case-sensitive. Furthermore, can you get a non-CUDA dll function to work in the same code?

RT

Share this post


Link to post
Share on other sites

Hello RTFC,

Thanks for your answer but there's not any mismatch, first one is the function called on device (GPU) and the second one called on the host (CPU). I try to export the function called on the host and the problem isn't the capitalisation because a simple dumpbin.exe /EXPORTS cuda.dll shows me that there's not any exported function.


When the words fail... music speaks

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Sorry, my mistake.:> So where do you actually declare your CPU function then? And what does that declaration look like?

AFAIK, to export your dll function(s), <yourdll>.h file should contain the declaration:

extern "C"
{

__declspec(dllexport) int Add(<params>);

}

and <yourdll>.cpp should contain the full definition:

#include <yourdll>.h

extern "C"
{

__declspec(dllexport) int Add(<params>)

{

<code>

}

}

That's just how I do it.

Edited by RTFC
addendum

Share this post


Link to post
Share on other sites

A DLL without export nor externs seems pretty useless.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

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

  • Similar Content

    • TrashBoat
      By TrashBoat
      Is this possible:
      Executing a function from an include, but taking the function name from a gui input and then executing that function using the include:
      #include <Something.au3> ;input reads "Tree" $functionName = GuiCtrlRead($input1) $functionName(1) And the include is gonna have
      Func Tree($x) If $x = 1 Then $this = "text" MsgBox(0,$this,"whatever") EndFunc is it possible?
    • junkew
      By junkew
      Since W8.1 (actually IE 11 with W7 will work also) microsoft has a Javascript runtime that can be called from scripting languages
      As shown in this example from C++: https://iobservable.net/blog/2013/11/12/introduction-to-jsrt/
      By loading either JSCRIPT9.DLL or CHAKRA.DLL you can embed ECMA JavaScript in your application
      And implemented here in AutoHotKey https://autohotkey.com/boards/viewtopic.php?f=6&t=5739
      Triggered by other threads: 
      https://www.autoitscript.com/forum/topic/185883-accessing-autoit-variables/ https://iobservable.net/blog/2013/11/12/introduction-to-jsrt/ https://www.autoitscript.com/forum/topic/184824-chakracore-udf-executing-javascript-in-autoit/ http://eclipsesource.com/blogs/2016/04/06/getting-started-with-microsoft-chakracore/
        This code is almost working but unfortunately not with the expected output. Someone seeing what is wrong? 
      It runs completely after fixes of DanyFirex 
       
      ;~ https://iobservable.net/blog/2013/11/ ;~ Should work on all windows versions with IE11 #AutoIt3Wrapper_UseX64=N #Region enum JsErrorCode : unsigned int Enum $JsNoError = 0, _ $JsErrorCategoryUsage = 0x10000, _ $JsErrorInvalidArgument, _ $JsErrorNullArgument, _ $JsErrorNoCurrentContext, _ $JsErrorInExceptionState, _ $JsErrorNotImplemented, _ $JsErrorWrongThread, _ $JsErrorRuntimeInUse, _ $JsErrorBadSerializedScript, _ $JsErrorInDisabledState, _ $JsErrorCannotDisableExecution, _ $JsErrorHeapEnumInProgress, _ $JsErrorArgumentNotObject, _ $JsErrorInProfileCallback, _ $JsErrorInThreadServiceCallback, _ $JsErrorCannotSerializeDebugScript, _ $JsErrorAlreadyDebuggingContext, _ $JsErrorAlreadyProfilingContext, _ $JsErrorIdleNotEnabled, _ $JsErrorCategoryEngine = 0x20000, _ $JsErrorOutOfMemory, _ $JsErrorCategoryScript = 0x30000, _ $JsErrorScriptException, _ $JsErrorScriptCompile, _ $JsErrorScriptTerminated, _ $JsErrorScriptEvalDisabled, _ $JsErrorCategoryFatal = 0x40000, _ $JsErrorFatal ;~ }JsErrorCode; #EndRegion enum JsErrorCode : unsigned int #Region typedef enum JsRuntimeVersion Enum $JsRuntimeVersion10 = 0, $JsRuntimeVersion11 = 1 #EndRegion typedef enum JsRuntimeVersion ; Create callback function. Local $hPrintf = DllCallbackRegister("_printf", "long", "ptr;bool;ptr;ushort;ptr") Local $hJSRuntime = DllOpen("c:\windows\system32\jscript9.dll") $JsRuntimeAttributeNone = 0x00000000 ;~ #RequireAdmin Example() Func Example() Local $script = "native.printf('hello world')" ;~ Local $script = "native.printf('number=%#x string=%s\n', 255, 'test')" ;~ Local $script = "(()=>{return 'Hello world!';})()" ;~ Local $script = "var x='helloworld'; return x;" ;~ Local $script = "var x=10;" & @CRLF & "var y=11;" ;~ Local $script = "(42);" ;~ Local $script = "(" & @CRLF ;~ $script=$script & "host.echo(JSON.stringify({foo:'bar'}));)" & @CRLF ;~ $script=$script & "42 // The script's result :) "& @CRLF ;~ $script=$script & ")"& @CRLF ;~ $script=$script & "class Host {"& @CRLF ;~ $script=$script & " echo(s) {"& @CRLF ;~ $script=$script & " MsgBox %s%"& @CRLF ;~ $script=$script & " }"& @CRLF ;~ $script=$script & "}"& @CRLF Local $aResult Local $runtime Local $context ;~ // Create a runtime ;~ JsCreateRuntime(JsRuntimeAttributeNone, nullptr, &runtime); $runtime = _JsCreateRuntime($JsRuntimeAttributeNone, 0, $runtime) ; ;~ // Create an execution context. ;~ JsCreateContext(runtime, &context); $context = _JsCreateContext($runtime, $context) ;~ // Now set the current execution context. ;~ JsSetCurrentContext(context); _JsSetCurrentContext($context) ; ; Get the Global object for adding stuff ;~ JsGetGlobalObject(&global); Local $global $global = _JsGetGlobalObject($global) ;~ JsPropertyIdRef nativeProp; ;~ JsGetPropertyIdFromName(L"native", &nativeProp); Local $nativeProp $nativeProp = _JsGetPropertyIdFromName("native", $nativeProp) ;~ JsValueRef nativeObj; ;~ JsCreateObject(&nativeObj); Local $nativeObj $nativeObj = _JsCreateObject($nativeObj) ;~ JsPropertyIdRef printfProp; ;~ JsGetPropertyIdFromName(L"printf", &printfProp); Local $printfProp $printfProp = _JsGetPropertyIdFromName("printf", $printfProp) ;~ JsValueRef printfFunc; ;~ JsCreateFunction(PrintFormat, nullptr, &printfFunc); Local $printfFunc $printfFunc = _JsCreateFunction(DllCallbackGetPtr($hPrintf), 0, $printfFunc) ;~ JsSetProperty(nativeObj, printfProp, printfFunc, true); _JsSetProperty($nativeObj, $printfProp, $printfFunc, True) ;~ JsSetProperty(global, nativeProp, nativeObj, true); _JsSetProperty($global, $nativeProp, $nativeObj, True) ;~ STDAPI_(JsErrorCode) JsCreateFunction( ;~ _In_ JsNativeFunction nativeFunction, ;~ _In_opt_ void *callbackState, ;~ _Out_ JsValueRef *function ;~ ); ; Get a JsValueRef for our Host object ;~ hostRef := ToJsValue(Host) ;~ $aResult=DllCall($hJSRuntime, "int","JsVariantToValue", "ptr", &variant, "ptr*", valref) ; Pass our Host object to the script engine ;~ DllCall("jscript9\JsSetProperty", "ptr", globalObject, "ptr", hostPropertyId, "ptr", hostRef, "int", true) ;~ // Run the script. ;~ STDAPI_(JsErrorCode) JsRunScript( ;~ _In_z_ const wchar_t *script, ;~ _In_ JsSourceContext sourceContext, ;~ _In_z_ const wchar_t *sourceUrl, ;~ _Out_ JsValueRef *result ;~ ); Local $currentSourceContext = 1 ;~ JsRunScript(script.c_str(), currentSourceContext++, L"", &result); Local $result = "" Local $sourceURL = "" $aResult = DllCall($hJSRuntime, "int", "JsRunScript", "WSTR", $script, "UINT*", $currentSourceContext, "wstr", "dummysource.js", "WSTR*", $result) ConsoleWrite("Error 11: " & @error & @CRLF) If @error = 0 Then ConsoleWrite($aResult[0] & ";" & $aResult[1] & ";" & $aResult[2] & ";" & $aResult[3] & ";" & $aResult[4] & @CRLF) EndIf ;~ // Convert your script result to String in JavaScript redundant if your script returns a String ;~ JsValueRef resultJSString; ;~ STDAPI_(JsErrorCode) JsConvertValueToString( ;~ _In_ JsValueRef value, ;~ _Out_ JsValueRef *stringValue ;~ ); ;~ JsConvertValueToString(result, &resultJSString); ;~ $aResult=DllCall($hJSRuntime, "int", "JsConvertValueToString", "WSTR", $script, "long", 1, "WSTR*",0, "WSTR*", $result) ;~ consolewrite("Error 4: " & @error & @CRLF) ;~ if @error=0 Then ;~ consolewrite($aResult[0] & ";" & $aResult[1] & ";" & $aResult[2] & ";" & $aResult[3] & ";" & $aResult[4] & @CRLF) ;~ EndIf ;~ ;~ // Project script result back to C++. ;~ const wchar_t *resultWC; ;~ size_t stringLength; ;~ JsStringToPointer(resultJSString, &resultWC, &stringLength); ;~ wstring resultW(resultWC); ;~ cout << string(resultW.begin(), resultW.end()) << endl; ;~ system("pause"); ;~ // Dispose runtime ;~ JsSetCurrentContext(JS_INVALID_REFERENCE); ;~ JsDisposeRuntime(runtime); Return 0 ; EndFunc ;==>Example ; Create callback function. ;~ JsValueRef CALLBACK PrintFormat(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState) ;~ { ;~ const wchar_t *format; ;~ size_t length; ;~ JsStringToPointer(arguments[1], &format, &length); ;~ VARIANT variant; ;~ JsValueToVariant(arguments[2], &variant); ;~ const wchar_t *str; ;~ JsStringToPointer(arguments[3], &str, &length); ;~ wprintf(format, variant.intVal, str); ;~ return JS_INVALID_REFERENCE; ;~ } ;~ typedef _Ret_maybenull_ JsValueRef (CALLBACK * JsNativeFunction)( ;~ _In_ JsValueRef callee, ;~ _In_ bool isConstructCall, ;~ _In_ JsValueRef *arguments, ;~ _In_ unsigned short argumentCount ;~ ); Func _printf($callee, $isConstructCall, $arguments, $argumentCount, $callbackState) ConsoleWrite("there we are with " & $argumentCount & " arguments" & @CRLF) Local $tArgs = DllStructCreate("ptr JsValues[" & $argumentCount & "]", $arguments) ;~ STDAPI_(JsErrorCode) JsConvertValueToString( ;~ _In_ JsValueRef value, ;~ _Out_ JsValueRef *stringValue ;~ ); ;~ JsConvertValueToString(result, &resultJSString); local $tresult $aResult=DllCall($hJSRuntime, "int", "JsConvertValueToString", "ptr", DllStructGetData($tArgs,1,2), "ptr*", $tresult) consolewrite("Error 4: " & @error & @CRLF) if @error=0 Then consolewrite( $aResult[0] & ";" & $aResult[1] & ";" & $aResult[2] & @CRLF) $tresult=$aresult[2] EndIf ;~ STDAPI_(JsErrorCode) JsValueToVariant( ;~ _In_ JsValueRef object, ;~ _Out_ VARIANT *variant ;~ ); ;~ Local $aResult = DllCall($hJSRuntime, "dword", "JsValueToVariant", "ptr", $arguments[0], "ptr*", 0) ;~ If @error Then Return SetError(3, 0, @error) ;~ If $aResult[0] <> 0 Then Return SetError(4, 0, $aResult[0]) ;~ consolewrite($aResult[2]) Local $aResult = DllCall($hJSRuntime, "dword", "JsStringToPointer", "ptr", $tResult, "ptr*", 0, "int*", 0) If @error Then Return SetError(3, 0, @error) If $aResult[0] <> 0 Then Return SetError(4, 0, $aResult[0]) Local $tString = DllStructCreate("wchar string["&$aResult[3]&"]", $aResult[2]) consolewrite("+Parameter: " & $tString.string & @CRLF) Return 0 EndFunc ;==>_printf ;~ typedef void *JsRuntimeHandle; ;~ // Create a runtime. ;~ Edge mode signature STDAPI_(JsErrorCode) JsCreateRuntime( ;~ _In_ JsRuntimeAttributes attributes, ;~ _In_opt_ JsThreadServiceCallback threadService, ;~ _Out_ JsRuntimeHandle *runtime); ;~ Legacy mode signature ;~ STDAPI_(JsErrorCode) JsCreateRuntime( ;~ _In_ JsRuntimeAttributes attributes, ;~ _In_ JsRuntimeVersion version, ;~ _In_opt_ JsThreadServiceCallback threadService, ;~ _Out_ JsRuntimeHandle *runtime ;~ ); ;~ $runtime=_JsCreateRuntime(JsRuntimeAttributeNone, 0, $runtime); Func _JsCreateRuntime($JsRuntimeAttributeNone, $JSRuntimeVersion, $runtime) $aResult = DllCall($hJSRuntime, "int", "JsCreateRuntime", "int", $JsRuntimeAttributeNone, "int", $JSRuntimeVersion, "ptr", 0, "ptr*", $runtime) If @error Then Return SetError(1, @error, 0) Return $aResult[4] EndFunc ;==>_JsCreateRuntime ;~ // Edge mode signature ;~ STDAPI_(JsErrorCode) JsCreateContext( ;~ _In_ JsRuntimeHandle runtime, ;~ _Out_ JsContextRef *newContext); ;~ // Legacy mode signature ;~ STDAPI_(JsErrorCode) JsCreateContext( ;~ _In_ JsRuntimeHandle runtime, ;~ _In_ IDebugApplication *debugApplication, ;~ _Out_ JsContextRef *newContext ;~ ); ;~ JsCreateContext(runtime, &context); Func _JsCreateContext($runtime, $context) $aResult = DllCall($hJSRuntime, "int", "JsCreateContext", "ptr", $runtime, "ptr", 0, "ptr*", $context) If @error Then Return SetError(1, @error, 0) Return $aResult[3] EndFunc ;==>_JsCreateContext ;~ STDAPI_(JsErrorCode) JsSetCurrentContext( ;~ _In_ JsContextRef context ;~ ); ;~ JsSetCurrentContext(context); Func _JsSetCurrentContext($context) $aResult = DllCall($hJSRuntime, "int", "JsSetCurrentContext", "ptr", $context) If @error Then Return SetError(1, @error, 0) Return $JsNoError EndFunc ;==>_JsSetCurrentContext ; Get the Global object for adding stuff ;~ STDAPI_(JsErrorCode) JsGetGlobalObject( ;~ _Out_ JsValueRef *globalObject ;~ ); ;~ JsValueRef global; ;~ JsGetGlobalObject(&global); Func _JsGetGlobalObject($global) $aResult = DllCall($hJSRuntime, "int", "JsGetGlobalObject", "ptr*", $global) If @error Then Return SetError(1, @error, 0) Return $aResult[1] EndFunc ;==>_JsGetGlobalObject ; Get a property ID for the name "host" ;~ STDAPI_(JsErrorCode) JsGetPropertyIdFromName( ;~ _In_z_ const wchar_t *name, ;~ _Out_ JsPropertyIdRef *propertyId ;~ ); ;~ DllCall("jscript9\JsGetPropertyIdFromName", "wstr", "host", "ptr*", hostPropertyId) ;~ local $hostPropertyID ;~ $aResult=DllCall($hJSRuntime, "int","JsGetPropertyIdFromName", "wstr", "host", "ptr*", $hostPropertyId) ;~ consolewrite("Error 5: " & @error & @CRLF) ;~ if @error=0 Then ;~ consolewrite($aResult[0] & ";" & $aResult[1] & ";" & $aResult[2] & @CRLF) ;~ EndIf ;~ JsPropertyIdRef nativeProp; ;~ JsGetPropertyIdFromName(L"native", &nativeProp); Func _JsGetPropertyIdFromName($propname, $nativeProp) $aResult = DllCall($hJSRuntime, "int", "JsGetPropertyIdFromName", "wstr", $propname, "ptr*", $nativeProp) If @error Then Return SetError(1, @error, 0) Return $aResult[2] EndFunc ;==>_JsGetPropertyIdFromName ;~ STDAPI_(JsErrorCode) JsCreateObject( ;~ _Out_ JsValueRef *object ;~ ); ;~ JsValueRef nativeObj; ;~ JsCreateObject(&nativeObj); Local $nativeObj Func _JsCreateObject($JSRTobject) $aResult = DllCall($hJSRuntime, "int", "JsCreateObject", "ptr*", $JSRTobject) If @error Then Return SetError(1, @error, 0) Return $aResult[1] EndFunc ;==>_JsCreateObject ;~ STDAPI_(JsErrorCode) JsCreateFunction( ;~ _In_ JsNativeFunction nativeFunction, ;~ _In_opt_ void *callbackState, ;~ _Out_ JsValueRef *function ;~ ); Func _JsCreateFunction($fncCallBackPtr, $callbackState, $fncVar) $aResult = DllCall($hJSRuntime, "int", "JsCreateFunction", "ptr", $fncCallBackPtr, "ptr*", $callbackState, "ptr*", $fncVar) If @error Then Return SetError(1, @error, 0) Return $aResult[3] EndFunc ;==>_JsCreateFunction ;~ JsSetProperty(nativeObj, printfProp, printfFunc, true); ;~ STDAPI_(JsErrorCode) JsSetProperty( ;~ _In_ JsValueRef object, ;~ _In_ JsPropertyIdRef propertyId, ;~ _In_ JsValueRef value, ;~ _In_ bool useStrictRules ;~ ); Func _JsSetProperty($Obj, $Prop, $Func, $val) ; $aResult = DllCall($hJSRuntime, "int", "JsSetProperty", "ptr", $Obj, "ptr", $Prop, "ptr", $Func, "int", $val) If @error Then Return SetError(1, @error, 0) EndFunc ;==>_JsSetProperty  
    • hcI
      By hcI
      Hello, i'm making a little script that lets users enter a question and if the script can't answer to, it ask what would be the answer (a bit like siri on IPhones). And I try to display the "supposed array" I still have an error.. I searched on Google and got nothing looked in the help file too.. I'm here to know if someone have a solution to my error please.
      Here is where $a and $b should become arrays :
      Dim $dossier = @AppDataDir & "\Siri2" Dim $chemin = $dossier & "\data.ini" Global $a = _InfoRead($chemin, 0) Global $b = _InfoRead($chemin, 1) with this function :
      Func _InfoRead($path, $mode = 0) If DirGetSize($dossier) = -1 Then Return SetError(-4) If Not FileExists($chemin) Then Return SetError(-5) Local $readed = IniReadSection($path, "data") If @error Then Return SetError(-3) $size = $readed[0][0] Local $return[$size] For $i = 1 To $size Step 1 $return[$i - 1] = $readed[$i][$mode] Next Return $return EndFunc and the thing that i don't understand is that, after _InfoRead return affected to $a, I can't use _ArrayDisplay because of  error 1 "$aArray is not an array" (and same fpr the variable $b)..
      Can please someone help me to understand why is it doing this ?

      -hcI
    • kawliga751
      By kawliga751
      I'm new to Auotit but I have built a simple script that "runs" a different "batch" file based on certain days of the workweek. The script works now, but I was wanting to eliminate the need for a manual date entry. For example "First Batch' needs to run every Tuesday thru Thursday however "Second Batch" needs to run only on Friday and "Third Batch" needs to run only on Monday. In addition the 1st batch file runs on Tuesday, say 06/06 (the "FW" section) but then needs to actually report (the F4 date) the next weekday so this Batch actually needs 2 dates verified. 
      What I'm trying to do is when the script is initiated it gets the date, verifies if and which weekday it is and in turn goes to and runs the appropriate "Batch' file.  
      I've found ways to verify weekdays but can't find anything to do all of the above.
      Any help is MUCH appreciated.
       
      ;P10
      ShellExecute("C:\Program Files (x86)\Ericom Software\PowerTerm Enterprise\Sessions\mir00p10.PTS")

      WinWait('(A) Soutwest P10 : PowerTerm Pro Enterprise Suite')
      WinActivate('(A) Soutwest P10 : PowerTerm Pro Enterprise Suite')
      Send('$Login)
      Sleep(3000)
      Send('{Enter}')
      Sleep(3000)
      Send($Password)
      Send('{Enter}')
      Sleep(3000)
      ; ****First Batch file run
      Send('Batch')
      Sleep(3000)
      Send('{Enter}')
      Send('FW')
      Send('{Enter}')
      Send('{DOWN}')
      Send($Date)
      Send('{Enter}')
      Send('{Enter}')
      Send($Date)
      Send('{F9}')
      Send('Y')
      Sleep(3000)
      Send('{Enter}')
      Send('{F4}')
      Send('Y')
      Sleep(3000)
      Send('{Enter}')
      Send($Date)
      Send('{Enter}')
      Send('0620')
      Send('{Enter}')
      SEND('{!}SW0410PM.FWR')
      Send('{Enter}')
      Sleep(3000)
      Send('Y')
      Send('{Enter}')
      Sleep(3000)
      Send('{F9}')
      Sleep(3000)
      ; ****Second Batch file run
      Send('Batch')
      Sleep(3000)
      Send('{Enter}')
      Send('FW')
      Send('{Enter}')
      Send('{DOWN}')
      Send($Date)
      Send('{Enter}')
      Send('{Enter}')
      Send($Date)
      Send('{F9}')
      Send('Y')
      Sleep(3000)
      Send('{Enter}')
      Send('{F4}')
      Send('Y')
      Sleep(3000)
      Send('{Enter}')
      Send($Date)
      Send('{Enter}')
      Send('0620')
      Send('{Enter}')
      SEND('{!}SO0411AM.FWR')
      Send('{Enter}')
      Sleep(3000)
      Send('Y')
      Send('{Enter}')
      Sleep(3000)
      Send('{F9}')
      Sleep(3000)
      ; ****Third Batch file run
      Send('Batch')
      Sleep(3000)
      Send('{Enter}')
      Send('FW')
      Send('{Enter}')
      Send('{DOWN}')
      Send($Date)
      Send('{Enter}')
      Send('{Enter}')
      Send($Date)
      Send('{F9}')
      Send('Y')
      Sleep(3000)
      Send('{Enter}')
      Send('{F4}')
      Send('Y')
      Sleep(3000)
      Send('{Enter}')
      Send($Date)
      Send('{Enter}')
      Send('0620')
      Send('{Enter}')
      SEND('{!}SW0411AM.LOA')
      Send('{Enter}')
      Sleep(3000)
      Send('Y')
      Send('{Enter}')
      Sleep(3000)
      Send('{F9}')
      Sleep(3000)
      Send('EXIT')
       
       
    • steveeye
      By steveeye
      Hi, can anybody explain "pure virtual function" and how to make use of them?