on 2013 Feb 20 2:47 PM
Hi,
I am trying to call some Win32API external functions in kernel32.dll from within SQL Anywhere 12.0.1 database server. Everything works well on 32-bit Windows (XP and 7), but nothing works on 64-bit Windows (7 and 8).
When I declare a function WITHOUT the LANGUAGE clause on 32-bit Windows, the function executes normally. When I do the same on 64-bit Windows I get the following error message:
"Version 'V0' interface used by external function call 'FunctionName' is not supported for execution in the current context."
When I declare a function WITH the LANGUAGE clause (C___ESQL32 or C_ESQL64) the error message disappears, the function seems to execute, but "does nothing". I can't get any return value or OUT arguments, everything is NULL. Executing functions in the external context (with the LANGUAGE clause) doesn't work at all, even on 32-bit Windows.
I have installed the latest EBF, tried with database engine and server, disabled antivirus and firewall - nothing helps. I have tried several Win32API functions: GetVersion, GetCurrentDirectoryA, GetVolumeInformationA, MessageBoxA, ... but here is the simplest example with a function that has no arguments:
create function SFGetVersion ( ) returns integer external name 'GetVersion@kernel32.dll' language C_ESQL32 (or C_ESQL64 for 64-bit Win); select SFGetVersion();
Where do I make mistake? Could anyone manage to get this function execute successfully in any context on 32-bit and 64-bit Windows? Is it possible at all to call Win32API functions from within SQL Anywhere server (I suppose it is - it works on 32-bit Win)?
Any help would be welcome. Thanks!
Request clarification before answering.
When calling an external function on Win64 you must use the "new" External Function API (new is relative since it has existed since v7). The "old" API is still allowed when using the 32bit server but its use is discouraged (it has not been updated since the new API was created).
In your particular case, the external DLL is missing the extfn_use_new_api() function and therefore the server thinks (correctly) that you are using the old API and it is not supported on 64bit platforms.
You can read more about writing external functions in the documentation. The install contains an example on how to use the new API as well.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Many thanks for your prompt reply! You probably spared me hours of useless experiments.
Just to be sure: definitely it is not possible anymore to directly call kernel32.dll, user32.dll and other Win32API functions on 64bit Windows platforms from within SQL Anywhere? Am I right?
And one more thing that still confuses me:
What do you exactly mean when you say "When CALLING an external function on Win64 you must use the "new" External Function API"? How "to use" the new API? When I CALL a function I don't use any API, except the one specified by the LANGUAGE clause. As I understand, the "new" API is used when you WRITE an external function. So, did you mean that I must write my own "intermediate" DLL, using "new" External Function API, and that functions from that DLL can in turn call eg. kernel32.dll functions?
Thank you once more!
If you are using a 32bit server on a 64bit platform then you should still be able to call directly into DLLs provided the server can find the correct one! ... but if you are using a 64bit server then you cannot call directly into the system DLLs.
Re. "how to use the new API", please refer to the documentation links that I gave in my answer, and/or read Breck's blog postings which he has listed in his answer. If you have further questions about using the API then please post a new question.
So you have used the "old API" to call external functions so far? (I'm somewhat surprised as the "new API" - as Mark has stated - has been introduced in ASA7, i.e. around the year 2000.)
IMHO, enhancing the existing API samples is not that difficult to do to call your required functions... - but of course you are right, it does require to write your own DLL, you can't simply call a WinAPI directly when using the "new API".
Why are you all folks talking about using the "old" or the "new" API to CALL external functions? What's the difference between using the "new" and the "old" API in the above mentioned example? Is there any new syntax to CALL an external function?
The "new" API has to be used when you WRITE your own functions in your own DLL or am I wrong? But I don't write any functions, I just want to call an existing function in kernel32.dll. How am I supposed to do it whit the "new" API?
Even today (13 years after the year 2000) SQL Anywhere do the job on 32-bit systems as it always have done (I have been using it for 18 years). That's why I am surprised that everything changes when you are on 64-bit system. Even when I write the new "wrapper" DLL for Win32API functions, the way I CALL that functions doesn't change.
Why are you all folks talking about using the "old" or the "new" API to CALL external functions? What's the difference between using the "new" and the "old" API in the above mentioned example? Is there any new syntax to CALL an external function?
No, the procedure call itself is the same, it's still "call MyFunc(...);".
Only the declaration will be different: As stated, to use the new external call API, you have to write your own DLL and can't call any standard DLL (as that won't have the extfn_use_new_api() function, apparently), so that DLL will be referred to in the function declaration.
Using the new API, you can then choose
I appreciate that there is some extra work for you to write a routine that interfaces between SA and the system function, but I would hope that writing such a routine would be very simple for you. The documentation and the SA installation as well as Breck's articles have many examples for you to get started.
Note that the new external function API provides many advantages over the former method:
http://sqlanywhere.blogspot.ca/2008/11/refactoring-foxhound-series.html Refactoring Foxhound: The Series
http://sqlanywhere.blogspot.ca/2009/02/get-mac-addresses-via-sql.html Get MAC Addresses Via SQL
http://sqlanywhere.blogspot.ca/2011/02/loading-32-bit-versus-64-bit-dlls.html Loading 32-bit Versus 64-bit DLLs
http://sqlanywhere.blogspot.ca/2011/02/loading-32-bit-versus-64-bit-dlls_16.html Loading 32-bit Versus 64-bit DLLs [revisited]
http://sqlanywhere.blogspot.ca/2012/12/calling-getopenfilename-from-sql.html Calling GetOpenFileName() From SQL
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
52 | |
10 | |
9 | |
8 | |
5 | |
5 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.