powderedtoastdude Posted May 14, 2007 Share Posted May 14, 2007 (edited) Hi! I'm puzzled by a DllCall problem. I've boiled it down to a simple test case which I'm attaching below. Basically: I have a trivial DLL that contains a function accepting an "int" parameter and returning an "int". When I call it with DllCall() but *don't* pass parameters to it, it succeeds. When I pass an int, it fails -- just terminates execution at call time with no apparent error. Here's the test case code. Any help very much appreciated! testcase.au3: Dim Const $dllname = "testcase.dll" $mainwindow = GUICreate("Test Case", 100, 100, 10, 10) GUISwitch($mainwindow) GUISetState(@SW_SHOW) $tcdll = DllOpen($dllname) If (-1 = $tcdll) Then errorexit("Can't open " & $dllname) ConsoleWrite("testing fn1" & @LF) $lhs = DllCall($tcdll, "int", "fn1") If (0 <> @error) Then errorexit("Calling fn1 results in error " & @error) ConsoleWrite("fn1 returns " & $lhs[0] & @LF) ConsoleWrite("testing fn2 with no input parameter" & @LF) $lhs = DllCall($tcdll, "int", "fn2") If (0 <> @error) Then errorexit("Calling fn2 results in error " & @error) ConsoleWrite("fn2 returns " & $lhs[0] & @LF) ConsoleWrite("testing fn2 with input parameter" & @LF) $lhs = DllCall($tcdll, "int", "fn2", "int", 3) If (0 <> @error) Then errorexit("Calling fn2 results in error " & @error) ConsoleWrite("fn2 returns " & $lhs[0] & @LF) DllClose($tcdll) Exit Func errorexit($msg) ConsoleWrite($msg & @LF) DllClose($tcdll) Exit EndFunc testcase.c: #include <stdio.h> #include <windows.h> #include "testcase.h" EXPORT int fn1() { return 42; } EXPORT int fn2(int n) { return 69 + n; } testcase.h: #ifndef __TESTCASE_H #define __TESTCASE_H #ifdef __cplusplus #define cppfudge "C" #else #define cppfudge #endif #ifdef BUILD_DLL // the dll exports #define EXPORT __declspec(dllexport) #else // the exe imports #define EXPORT extern cppfudge __declspec(dllimport) #endif EXPORT int fn1(); EXPORT int fn2(int); #endif And of course the output: >"C:\Program Files\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "Z:\dev\elrapido\testcase.au3" testing fn1 fn1 returns 42 testing fn2 with no input parameter fn2 returns 69 testing fn2 with input parameter >Exit code: 0 Time: 0.334 Edited May 14, 2007 by powderedtoastdude Link to comment Share on other sites More sharing options...
martin Posted May 14, 2007 Share Posted May 14, 2007 Hi! I'm puzzled by a DllCall problem. I've boiled it down to a simple test case which I'm attaching below. Basically: I have a trivial DLL that contains a function accepting an "int" parameter and returning an "int". When I call it with DllCall() but *don't* pass parameters to it, it succeeds. When I pass an int, it fails -- just terminates execution at call time with no apparent error. Here's the test case code. Any help very much appreciated! testcase.au3: Dim Const $dllname = "testcase.dll" $mainwindow = GUICreate("Test Case", 100, 100, 10, 10) GUISwitch($mainwindow) GUISetState(@SW_SHOW) $tcdll = DllOpen($dllname) If (-1 = $tcdll) Then errorexit("Can't open " & $dllname) ConsoleWrite("testing fn1" & @LF) $lhs = DllCall($tcdll, "int", "fn1") If (0 <> @error) Then errorexit("Calling fn1 results in error " & @error) ConsoleWrite("fn1 returns " & $lhs[0] & @LF) ConsoleWrite("testing fn2 with no input parameter" & @LF) $lhs = DllCall($tcdll, "int", "fn2") If (0 <> @error) Then errorexit("Calling fn2 results in error " & @error) ConsoleWrite("fn2 returns " & $lhs[0] & @LF) ConsoleWrite("testing fn2 with input parameter" & @LF) $lhs = DllCall($tcdll, "int", "fn2", "int", 3) If (0 <> @error) Then errorexit("Calling fn2 results in error " & @error) ConsoleWrite("fn2 returns " & $lhs[0] & @LF) DllClose($tcdll) Exit Func errorexit($msg) ConsoleWrite($msg & @LF) DllClose($tcdll) Exit EndFunc testcase.c: #include <stdio.h> #include <windows.h> #include "testcase.h" EXPORT int fn1() { return 42; } EXPORT int fn2(int n) { return 69 + n; } testcase.h: #ifndef __TESTCASE_H #define __TESTCASE_H #ifdef __cplusplus #define cppfudge "C" #else #define cppfudge #endif #ifdef BUILD_DLL // the dll exports #define EXPORT __declspec(dllexport) #else // the exe imports #define EXPORT extern cppfudge __declspec(dllimport) #endif EXPORT int fn1(); EXPORT int fn2(int); #endif And of course the output: >"C:\Program Files\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "Z:\dev\elrapido\testcase.au3" testing fn1 fn1 returns 42 testing fn2 with no input parameter fn2 returns 69 testing fn2 with input parameter >Exit code: 0 Time: 0.334 I know almost nothing about C++, but is it possible you need to use the "int:cdecl" as described in the help? By default, AutoIt uses the 'stdcall' calling method. To use the 'cdecl' method place ':cdecl' after the return type. DllCall("SQLite.dll", "int:cdecl", "sqlite3_open", "str", $sDatabase_Filename , "long_ptr", 0). Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
powderedtoastdude Posted May 14, 2007 Author Share Posted May 14, 2007 I know almost nothing about C++, but is it possible you need to use the "int:cdecl" as described in the help?Tried that... when I use "int:cdecl", for either the input parameter or the return value or both, I get @error = 2 (unknown return type). So I concluded that was the wrong thing to do. Link to comment Share on other sites More sharing options...
powderedtoastdude Posted May 14, 2007 Author Share Posted May 14, 2007 Tried that... when I use "int:cdecl", for either the input parameter or the return value or both, I get @error = 2 (unknown return type). So I concluded that was the wrong thing to do.My bad. Apparently I tried it on the input parameter and both, but not on just the return value. Dunno why, but it works now! Thanks.Homemade DLLs are fun. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now