Logic(_cast... crashes VO & DBCreate question

This forum is meant for questions and discussions about the X# language and tools
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Logic(_cast... crashes VO & DBCreate question

Post by ic2 »

Basically my problem is that every time I resume working on an older X# project with a newer X# version installed I am getting al kind of new problems which are difficult to detect and solve.

1 This used to work:

RDDSetDefault("DBFCDX")
oExcel:=ApplicationClass{}
oExcel:Visible:=False // Don't show the EXCEL execute
oExcel:DisplayAlerts:=False // Don't show messages
oWorkBooks:=oExcel:Workbooks
ofd:=Microsoft.Win32.OpenFileDialog{}
ofd:Filter:="Excel Files|*.xlsx;*.xls"
lResult:=ofd:ShowDialog()

I had to change the last line as follows because of error XS0266 Cannot implicitely convert type logic? to logic

lResult:=Logic(_cast,ofd:ShowDialog())

Now, the first time I actually created the X# DLL to be used in VO, with some changes (see below) VO crashed with a 5333 (also when there's an error handler Try/Catch; it doesn't show a run time error). It took me nearly an hour, by gradually adding code, to find out where it went wrong:

lResult:=Logic(_cast,ofd:ShowDialog())

causes the 5333. If I just make it ofd:ShowDialog() it works, but I can not read the result of opening the file!

How can I get this working without crashing VO? I tried to disable this error with the #pragma statement but that does only seem to work with warnings.

Edit: Also I am not seeing how you have declared the "ofd" variable. That should be

LOCAL ofd AS Microsoft.Win32.OpenFileDialog

2 The reason why I had to change the program is that when I create the DBF (from an Excel file) I get this error:

Vulcan.NET Runtime Error
Error Code: 1 [Argument error]
Error Subcode: 1015 [RDD not found]

which seems to indicate that

If DBCreate("ExcelImport.dbf", aDBF) does no longer work (it used to!) and requires at least DBFCDX to be supplied, I thought:
If DBCreate("ExcelImport.dbf", aDBF,"DBFCDX")

But it doesn't work with DBFCDX filled in either. Also this used to work fine. Note that I use the Vulcan DLL's because of multiple problems with the X# DBF DLL's.

So why do I get this error? I have copied all the DLL's and there are no X# specific RDD's as far as I can see?

3 And another thing which intrigued me is why the last parameters of the DBCreate method differ from those in VO?

Dick
FFF
Posts: 1580
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

Logic(_cast... crashes VO & DBCreate question

Post by FFF »

Dick,
you don't say, which version you use, that doesn't help...
In the What's new for 2.7 there is "Fixed a problem with Nullable types that were missing an explicit cast for an assignment" - if you look into MS doc you see ShowDialog() returns a "bool?" - not a "bool". Hence the error. If you are on 2.6 it might be related to this fix.
I have no clue of these new things, but couldn't you type your "lResult as logic?" (insteat of "logic")?
(I hate all these question marks...)

Re 2 i have no clue, but from the help this should be the same as in VO.
Re 3 i see no difference

And finally: If you have "multiple problems with X# Dlls", it would be nice, if you post them - hence others won't get trapped - and dev has a chance to fix them.

EDIT: Re1: i added this to a X# Standard MDI sample (after adding reference to "Presentation")
VAR ofd:=Microsoft.Win32.OpenFileDialog{}
ofd:Filter:="Excel Files|*.xlsx;*.xls"
VAR lResult:=ofd:ShowDialog()

No warning, dialog shown, filter set.
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Logic(_cast... crashes VO & DBCreate question

Post by Chris »

Hi Dick,

1. What changed is a fix we made in the compiler (as Karl pointed out), because there was a problem previously in this area, with Nullable types and in this case ShowDialog() returns a Nullable LOGIC. It was working for you before in this case only by coincidence, because apparently this particular method only returns TRUE or FALSE and never NULL. Other similar code would had failed, and now we have fixed that, but the change means that now you need to use correct code when dealing with Nullables.

Nullable LOGICs have 3 states, TRUE, FALSE or NULL. The correct way to read the value is to query first if the return type has a value (TRUE or FALSE) and only then read it:

Code: Select all

	lRetValue := ofd:ShowDialog()
	IF lRetValue:HasValue
		lResult := lRetValue:Value
	ELSE
		// what does NULL return value mean? Maybe handle it as FALSE, too?
		lResult := FALSE
	END IF
if you are absolutely sure that the method never returns NULL (which according to the docs appears to be the case with ShowDialog() here), then you could have also read the logic value directly, but this is really sloppy coding when dealing with nullables:

Code: Select all

lResult := ofd:ShowDialog():Value

2. This does work fine still. Could it be the error is reported in some other part of your code?

3. Which ones are different? They look to be exactly the same here.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Logic(_cast... crashes VO & DBCreate question

Post by ic2 »

Hello Chris, Karl,I tried this code (combining both your replies):

LOCAL lResult as USUAL

Var lRetValue:=ofd:ShowDialog()
If lRetValue:HasValue
lResult:=lRetValue
Endif

If lResult == False
Return
Else
cExcelFile:=ofd:FileName
Endif


That works indeed, thanks, but I am not comfortable with the USUAL. Can I change that and how?

2 See attached the full error message. This seems to fail at DBCreate. I just can't figure out what is supposed to be missing (or wrong)?
It is not possible to debug this as it's a DLL called from VO but I have added a Messagebox just before and just after the DBCreate and the first shows and before the 2nd can be reached I have the error message.

Note that this works, at the start of the program:
RDDSetDefault("DBFCDX")
and this fails:

If DBCreate("ExcelImport.dbf", aDBF,"DBFCDX",True,"","",False) // Create the DBF

and omitting DBFCDX gives an exception String can not have zero length.

According to the help:

If not specified, the default RDD as determined by RDDSetDefault() is used.

so that doesn't seem to work as specified either:

If DBCreate("ExcelImport.dbf", aDBF,"",True,"","",False) // Create the DBF




3 I think you are right. VO calls it:

DBCreate(<cTargetFile>, <aStruct>, [<cDriver>], [<lNew>], [<cAlias>], [<cDelim>], [<lOpen>],, [<acRDDs>]) ---> lSuccess

and the tooltip in X# calls the last 2 parameters lJustOpen and aHidden. No idea why the latter is called aHidden but I assume it is the same array as VO's acRDDs.

Dick
Attachments
Error1015XS.jpg
Error1015XS.jpg (41.55 KiB) Viewed 677 times
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Logic(_cast... crashes VO & DBCreate question

Post by Chris »

Hi Dick,

1. No need to use a USUAL, just type it AS LOGIC

2. Oh, I forgot that this is called from VO. Did you include the code to initialize the vulcan rdd? You must have needed this also before.

About the driver name, the help file says you can omit this parameter, but in this case you are not omitting it, you are passing an empty string instead. Omitting it would look like:

DBCreate("ExcelImport.dbf", aDBF, ,True)

3. If you see the tooltip in VO, it has the exact same parameter names as in X#/Vulcan
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
FFF
Posts: 1580
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

Logic(_cast... crashes VO & DBCreate question

Post by FFF »

Chris,
typing as logic won't work, compiler won't accept it.
But LOCAL lResult AS LOGIC?
works.
Dick,
either the above, or my
VAR lResult := ofd:ShowDialog()
should work.
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Logic(_cast... crashes VO & DBCreate question

Post by Chris »

Hi Karl,

It doesn't work, because Dick changed the code from "lResult := lRetValue:Value" to "lResult := lRetValue". The correct first version of the code works. But anyway since the return value is not being used anywhere later as far as I can see, then the code can be simply written as

Code: Select all

LOCAL lResult AS Nullable<LOGIC>
lResult := ofd:ShowDialog()
IF lResult:HasValue .and. lResult:Value == TRUE
	cExcelFile := ofd:FileName
ELSE
	RETURN
ENDIF
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
FFF
Posts: 1580
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

Logic(_cast... crashes VO & DBCreate question

Post by FFF »

Ah, i see.
FTR: it seems,
LOCAL lResult AS Nullable<LOGIC>
is equal to
LOCAL lResult AS LOGIC?
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Logic(_cast... crashes VO & DBCreate question

Post by Chris »

Yes, it's exactly the same thing, I just prefer the Nullable<> version because for me it's more readable.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Logic(_cast... crashes VO & DBCreate question

Post by ic2 »

1. No need to use a USUAL, just type it AS LOGIC

LOCAL lResult AS Nullable<LOGIC>

That works indeed, thanks.

2. Oh, I forgot that this is called from VO. Did you include the code to initialize the vulcan rdd? You must have needed this also before.

It worked before as it is now, but what should I do to initialize?

About the driver name, the help file says you can omit this parameter, but in this case you are not omitting it, you are passing an empty string instead. Omitting it would look like:

Ah, of course. But then it still doesn't work.

Maybe the initialize helps....

Dick
Post Reply