xsharp.eu • Xported project: Error XS1061 'type' does not contain a definition for ..
Page 1 of 2

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 10:47 am
by ic2
In an XPorter converted VO project we get a few 100 errors like this:


Error XS1061 '__Usual' does not contain a definition for 'Close' and no extension method 'Close' accepting a first argument of type '__Usual' could be found (are you missing a using directive or an assembly reference?)

Code is simple things like:
SELF:Server:Close()
All Vulcan includes are present and Treat missing types as usual is True.

What helps is to set Allow Late binding to true; then the errors disappear. But apart from that it's not completely clear to me what I am doing, it should not be necessary. We have other working projects without this option. I am obviously missing something but I can't see what.

PS: the X# CHM help shows both for the /lb compiler option and the XS1061 error Example code. For the /lb it only shows empty boxes; for the XS1061 it only shows // XS1061.prg in the box. So the actual example code is missing.

Dick

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 11:07 am
by wriedmann
Hi Dick,

I'm answering because I had a similar problem and have discussed it with Chris.

For VO projects, you need late binding.

Otherwise you have to type all these objects or cast them to something, or use the Send() function (as I did because in my code a typing was not possible because in my application the types were available only at runtime, and not at compile time).

Wolfgang

P.S. removing this option would need a rewrite of your code, and a strong adoption of interfaces

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 11:18 am
by ic2
Hello Wolfgang,

Ok - but if I change it to a Vulcan project I get the same number of errors. Vulcan libraries are included so I'd expect something like self:Server to be available at compile time?

Other errors refer to GUI elements, like self:browser or something like SELF:ToolBar:PressItem(IDM_StandardShellMenu_View_Table_ID)

Dick

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 11:34 am
by wriedmann
Hi Dick,

self:Server in the class DataWindow is a non typed access variable, so the compiler cannot know what type it returns.
Therefore it is of type "usual", and the datatype "usual" has no method Close().
The compiler is also right.
If you use the "late binding" option in the compiler, under the hood the compiler translates

Code: Select all

oWindow:Server:Close()
to code similar to

Code: Select all

Send( oWindow:Server, "Close" )
And therefore the method call will be resolved at runtime and not at compile time - also late binding.

Wolfgang

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 12:07 pm
by ic2
Thanks Wolfgang,

It looks like that's indeed the case. I have one other X# solution without Late Binding but this opens databases directly, like

SELF:oDBSomedb := IC2DBServer{cDataPath + "somedb.dbf", TRUE, FALSE}

and

CLASS IC2DbServer INHERIT DbServer
CONSTRUCTOR (oDbf_FS, lShare, lReadOnly) // Class IC2DBServer
SUPER(oDbf_FS, lShare, lReadOnly)


Then it works without this error. So it probably works without Late binding if we subclass self:server as above.We have to check that.

Point is otherwise that I wonder how much we actually gain from converting VO projects to X# with late binding on. From the documentation: late-bound calls can affect the performance.

Plus compiler errors which would normally point to a method which isn't available at runtime either are suppressed so it will actually make your X# program much more vulnerable to run time errors than a VO program. E.g. this compiles fine:

SELF:Server:Dosomethingwhichdoesnotexist()


Dick

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 12:07 pm
by Chris
Hi DIck,

It's exactly what Wolfgang said, in SELF:Server:Close(), "Server" is known ar compile time, but its type is USUAL and "Close()" is not known at compile time, this will be resolved at runtime, thus late binding is necessary.

It would had been completely different if "Server" was strongly typed in the SDK, so it was declared for example as

ACCESS Server AS DataServer

in this case, everything would be known at compile time and no lated binding would be involved at all.

CHris

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 12:10 pm
by Chris
Hi Dick,
ic2 wrote: Plus compiler errors which would normally point to a method which isn't available at runtime either are suppressed so it will actually make your X# program much more vulnerable to run time errors than a VO program. E.g. this compiles fine:

SELF:Server:Dosomethingwhichdoesnotexist()
Exactly, absolutely the same as in VO...For these reason it is useful equivalently in both VO and X# to use early binding than late binding.

Chris

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 12:18 pm
by wriedmann
Hi Dick,

no, this has not to do with your subclassed server, but probably self:oSomeDB is known at compile time (either as instance variable or as strong typed access). Therefore the compiler knows the correct method to call at compile time.
Point is otherwise that I wonder how much we actually gain from converting VO projects to X# with late binding on. From the documentation: late-bound calls can affect the performance.

Plus compiler errors which would normally point to a method which isn't available at runtime either are suppressed so it will actually make your X# program much more vulnerable to run time errors than a VO program. E.g. this compiles fine:

SELF:Server:Dosomethingwhichdoesnotexist()
In VO, you are using late binding. Therefore I don't think X# will be slower or less stable if you are using late binding with it.

I have to confess that I use late binding a lot, and also the Send(), IVarGet() and IVarPut() functions.

To make stable and performant code for sure late binding is not the best option, but it makes me much more productive.
Otherwise you will have to work with interfaces, and rethink the application structure.

This may be the case for new applications, but for sure not for migrated ones.

Fortunately X# gives us the choice: late binding as in VO or not.

Wolfgang

P.S. I would like a pragma in the code to switch late binding on or of when needed....

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 12:37 pm
by ic2
Hello Chris, Wolfgang,
Exactly, absolutely the same as in VO...For these reason it is useful equivalently in both VO and X# to use early binding than late binding.
Indeed! I never realized that but VO accepts this too. And we also use send(#) regularly in VO; e.g. we have a couple of main programs for different client(types) where sometimes a client (type) specific methods replaces the regular method and this one resides in the main program which we can call from the included lib thanks to ismethod and send(#).

So good to know that I didn't miss something obvious and late binding is a normal practice. I assume this can be abandoned as soon as we have the Core X#.

Dick

Xported project: Error XS1061 'type' does not contain a definition for ..

Posted: Wed Sep 05, 2018 1:42 pm
by FFF
ic2 wrote:I assume this can be abandoned as soon as we have the Core X#.
If "this" means, late binding, i wouldn't know, why. LB lets you use calls to types you don't know at compile time, that won't change because the runtime changes.

Karl