I've got 3 issues when replacing Vulcan DLL's with X# DLL's in an existing X# project. Not sure how to solve these:
1 In November 2013 Chris sent me the following code and explanation. The reason was that I could not call WCF code on a website from X# (it crashed) while it did work using C#, and this solved it (somehow)
CLASS DummyClass
END CLASS
and in your code, make sure this is called as the _FIRST_ line of any vulcan code executed:
Vulcan.Runtime.State.AppModule := TypeOf(DummyClass):Module
It may well be possible that it works fine in X# but I prefer to change as little as possible so I changed it to:
XSharp.Core.AppModule := TYPEOF(DummyClass):Module (according to the help, AppModule is part of X#.Core)
However, I get this error:
Error XS0234 The type or namespace name 'AppModule' does not exist in the namespace 'XSharp.Core' (are you missing an assembly reference?)
What should I change?
2 This one is less important, because I don't seem to even use it, but I had a changed DBCreate function in my code. This ends with code called when VODBCreate would return false:
If !lRetCode
lRetCode := DoError(#DBCREATE)
Endif
This gives a conversion error (DoError returns an object and lRetCode is a logic). So the error is clear and correct, but what is DoError supposed to be doing in DBCreate? Just out of curiosity!
3 In the Vulcan DLL X# program I use:
Ace.AdsConnect101, ACE.AdsOpenTable101, ACE.AdsExecuteSQLDirectW. None of these are present in XSharp.ADS.
I see there Ace.AdsConnect60, ACE.AdsOpenTable90, ACE.AdsExecuteSQLDirect but these differ a lot in parameters so I have to figure out what all those parameters need to be (AdsOpenTable101 is 3 and AdsOpenTable101 is 10 parameters) and it increases the chance that something is going to work differently (or not).
So mainly my questions are:
1 Can't I use the original Vulcan recognized methods somehow?
2 Why has these functions changed so much?
Dick
3 Issues when replacing Vulcan DLL's with X# DLL's
3 Issues when replacing Vulcan DLL's with X# DLL's
Hi Dick,
1. In X# this should be:
the second line is an additional one and not necessary, but will provide 100% compatibility with VO, if you are indeed using the VO dialect (remove this if you are using Core dialect).
2. This just looks like wrong code, I don't see how DoError() could return a logic value, even in vulcan. Not sure what your code is supposed to do exactly, maybe if you post the complete code of the function it will be more clear.
3. Well, it's the ADS developers who changed the signatures of the methods in different ADS versions, I am guessing in order to support more features in their system.
As for why some (or many) functions are not available in the X# runtime, I am guessing the only reason is that there exist literally 100s of such ADS functions and Robert has so far added the most commonly used ones. The rest can be added when needed, I looked into the Vulcan ADS RDD and those functions are defined as follows, hope I have not made a mistake! Simply include this code in one of your libraries and you will just need to call those with ACE2.AdsOpenTable101() now (ACE2 instead of ACE), as they are included in a new class name:
1. In X# this should be:
Code: Select all
XSharp.RuntimeState.AppModule := TypeOf(TestClass):Module
XSharp.RuntimeState.Dialect := XSharp.XSharpDialect.VO
2. This just looks like wrong code, I don't see how DoError() could return a logic value, even in vulcan. Not sure what your code is supposed to do exactly, maybe if you post the complete code of the function it will be more clear.
3. Well, it's the ADS developers who changed the signatures of the methods in different ADS versions, I am guessing in order to support more features in their system.
As for why some (or many) functions are not available in the X# runtime, I am guessing the only reason is that there exist literally 100s of such ADS functions and Robert has so far added the most commonly used ones. The rest can be added when needed, I looked into the Vulcan ADS RDD and those functions are defined as follows, hope I have not made a mistake! Simply include this code in one of your libraries and you will just need to call those with ACE2.AdsOpenTable101() now (ACE2 instead of ACE), as they are included in a new class name:
Code: Select all
USING System.Runtime.InteropServices;
CLASS ACE2
PUBLIC STATIC METHOD AdsConnect101(pucConnectString AS STRING, phConnectionOptions OUT IntPtr, phConnect OUT IntPtr ) AS DWORD
IF IntPtr.Size == 4
RETURN AdsConnect101_32(pucConnectString, OUT phConnectionOptions, OUT phConnect)
ELSE
RETURN AdsConnect101_64(pucConnectString, OUT phConnectionOptions, OUT phConnect)
ENDIF
PUBLIC STATIC METHOD AdsConnect101(pucConnectString AS STRING, phNullOptions AS IntPtr , phConnect OUT IntPtr) AS DWORD
IF IntPtr.Size == 4
RETURN AdsConnect101_32(pucConnectString, phNullOptions, OUT phConnect)
ELSE
RETURN AdsConnect101_64(pucConnectString, phNullOptions, OUT phConnect)
ENDIF
[DllImport("ace32.dll", CharSet := CharSet.Ansi, EntryPoint := "AdsConnect101")];
PRIVATE STATIC EXTERN METHOD AdsConnect101_32(pucConnectString AS STRING, phConnectionOptions OUT IntPtr, phConnect OUT IntPtr ) AS DWORD
[DllImport("ace32.dll", CharSet := CharSet.Ansi, EntryPoint := "AdsConnect101")];
PRIVATE STATIC EXTERN METHOD AdsConnect101_32(pucConnectString AS STRING, phNullOptions AS IntPtr, phConnect OUT IntPtr ) AS DWORD
[DllImport("ace64.dll", CharSet := CharSet.Ansi, EntryPoint := "AdsConnect101")];
PRIVATE STATIC EXTERN METHOD AdsConnect101_64(pucConnectString AS STRING, phConnectionOptions OUT IntPtr , phConnect OUT IntPtr) AS DWORD
[DllImport("ace64.dll", CharSet := CharSet.Ansi, EntryPoint := "AdsConnect101")];
PRIVATE STATIC EXTERN METHOD AdsConnect101_64(pucConnectString AS STRING, phNullOptions AS IntPtr, phConnect OUT IntPtr ) AS DWORD
PUBLIC STATIC METHOD AdsOpenTable101(hConnect AS IntPtr, pucName AS STRING, phTable OUT IntPtr ) AS DWORD
IF IntPtr.Size == 4
RETURN AdsOpenTable101_32(hConnect, pucName, OUT phTable)
ELSE
RETURN AdsOpenTable101_64(hConnect, pucName, OUT phTable)
ENDIF
[DllImport("ace32.dll", CharSet := CharSet.Ansi, EntryPoint := "AdsOpenTable101")];
PRIVATE STATIC EXTERN METHOD AdsOpenTable101_32(hConnect AS IntPtr, pucName AS STRING, phTable OUT IntPtr ) AS DWORD
[DllImport("ace64.dll", CharSet := CharSet.Ansi, EntryPoint := "AdsOpenTable101")];
PRIVATE STATIC EXTERN METHOD AdsOpenTable101_64(hConnect AS IntPtr, pucName AS STRING, phTable OUT IntPtr ) AS DWORD
PUBLIC STATIC METHOD AdsExecuteSQLDirectW(hStatement AS IntPtr, pwcSQL AS STRING, phCursor OUT IntPtr) AS DWORD
IF IntPtr.Size == 4
RETURN AdsExecuteSQLDirectW_32(hStatement, pwcSQL, OUT phCursor)
ELSE
RETURN AdsExecuteSQLDirectW_64(hStatement, pwcSQL, OUT phCursor)
ENDIF
[DllImport("ace32.dll", CharSet := CharSet.Unicode, EntryPoint := "AdsExecuteSQLDirectW")];
PRIVATE STATIC EXTERN METHOD AdsExecuteSQLDirectW_32(hStatement AS IntPtr, pwcSQL AS STRING, phCursor OUT IntPtr) AS DWORD
[DllImport("ace64.dll", CharSet := CharSet.Unicode, EntryPoint := "AdsExecuteSQLDirectW")];
PRIVATE STATIC EXTERN METHOD AdsExecuteSQLDirectW_64(hStatement AS IntPtr, pwcSQL AS STRING, phCursor OUT IntPtr) AS DWORD
END CLASS
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
3 Issues when replacing Vulcan DLL's with X# DLL's
Hello Chris,
Thanks for the very quick reply! The AppModule replacement compilers, I'll add the ACE32 code and see if everything still works as it did.
The DoError question, well I have no idea why it put it there (it is not used). But I see that the last part is 100% from the VO SDK (Function DBCREATE in RDD of System library), below the last few lines.
I am just curious what DoError is supposed to "Do" ?
Dick
lRetCode := VODBCreate(cName, aStru, rddList, lNew, cAlias, cDelim, lKeep, lJustOpen)
IF rddList != NULL_PTR
MemFree(RDDLIST)
ENDIF
IF !lRetCode
lRetCode := DoError(#DBCREATE)
ENDIF
RETURN lRetCode
Thanks for the very quick reply! The AppModule replacement compilers, I'll add the ACE32 code and see if everything still works as it did.
The DoError question, well I have no idea why it put it there (it is not used). But I see that the last part is 100% from the VO SDK (Function DBCREATE in RDD of System library), below the last few lines.
I am just curious what DoError is supposed to "Do" ?
Dick
lRetCode := VODBCreate(cName, aStru, rddList, lNew, cAlias, cDelim, lKeep, lJustOpen)
IF rddList != NULL_PTR
MemFree(RDDLIST)
ENDIF
IF !lRetCode
lRetCode := DoError(#DBCREATE)
ENDIF
RETURN lRetCode
3 Issues when replacing Vulcan DLL's with X# DLL's
Hi Dick,
It's used for low level error handling and I see this code existed in the VO/vulcan runtime, maybe you got it from there, although you did not post the complete source of the functions, so I am not sure. In any case, since you are not using this at all and do not know why you have added it, I think the best way to deal with this is to simply remove this.
It's used for low level error handling and I see this code existed in the VO/vulcan runtime, maybe you got it from there, although you did not post the complete source of the functions, so I am not sure. In any case, since you are not using this at all and do not know why you have added it, I think the best way to deal with this is to simply remove this.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu