Re: C# Plugin system - same interface in two different assemblies...



WTH wrote:

"Jeroen Mostert" <jmostert@xxxxxxxxx> wrote in message news:478f8c75$0$85790$e4fe514c@xxxxxxxxxxxxxxxxx
WTH wrote:
It's supposed to work that way because it does? No offense but types are already treated as if they were fully dynamic and assemblies contain entire type definitions including inheritance, ergo, it is EASY for the runtime to recursively evaluate the types.

Sure. It's also costly. If we go for consistency, those typing rules would need to apply to every single type, presumably down to the primitive types that you can't define.

It doesn't have to be by default. There's no reason you coulnd't have an attribute on a type that specified that the type in question should be eligible for this type of treatment.

OK, that's an interesting solution. Yes, they could have included something like that. They still can if we ever get around to CLR 3.0.

We're talking a completely different approach to typing here. I find it
easy to see why the .NET designers went with the tried and true approach of just checking a unique identifier for each type (that is, full type name, including assembly version). More intricate type systems that fully accommodate "duck typing" are certainly possible, but TANSTAAFL.

I can understand that, but then why does reflection exist at all except to allow, when necessary, the slow and methodical evaluation of types for the purpose of understanding their usages and capabilities...?

Reflection is just dandy, but it's no basis for a type system of a statically typed language. It's a "hey, if you can't do it that way, there's always reflection, I mean, if you have to" solution. And for sure, you can solve the problem you've got with reflection too. It would be horrible, but you could do it.

This discussion is extremely old. What's the identity of a type? Is it its name, its structure, a combination of the two? Every language needs to pick. You disagree with the choice the designers made. Which is fine, but they didn't make the choices they did just to spite you. They went for "easy to understand" and "will never go wrong".

Again, I don't care if they are identified as different. I care that the runtime cannot recognize that they are totally compatible types, that they can be cast to one another or used identically. That's what I care about. Now, the compiler identifying them as the same, is not possible (for security reasons), so I'm not interested in them being considered the same definition, I'm interested in them being considered two different definitions of the exact same thing and therefore interchangeable.

Ah, I see what you're getting at now. You're not interested in unifying the types, you want the runtime to transparently marshal between these nominally different types, after recognizing that this is possible. This is essentially what you achieve with COM by saying "yes, I implement this interface with this UID too", but then you want it by structural compatibility, not an agreed-upon UID.

Hehe, does this send shivers down your spine? lpVtbl->

"Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn" sounds less scary.

What you want would work in C++, because C++ doesn't do runtime checks of any kind. Even then, it would only work if the compilers produced compatible object files. If not, then prepare for crashes.

? I'm not sure what you mean, as GCC, Intel, and Microsoft's compilers all produce compatible plugins for several products in our product suite. They work just fine.

That's because they have had to converge to make it work. As long as you don't get subtle with multiple inheritance, method pointers or exceptions, those compilers will all produce the same low-level binary stuff to make sure it'll work with the other compilers. This is also the foundation of COM. Any option that influences the way the compiler lays out vtables will break it, though. They work "just fine" because people before you suffered.

Your argument doesn't make sense to me. You're trying to say its a bad approach because it has forced compiler writers to agree to calling conventions and function table layouts?

No, I'm just saying it can't be compared to the .NET approach because nobody in the C++ world is required to play by any rules. If it happens to work, it happens to work, and if it doesn't happen to work it's the programmer's task to clean up. .NET just gives you things that will work, and it will protect you from the things that wouldn't work. The designers will naturally be inclined to be conservative with such an outlook, instead of giving you everything that could have been useful.

Personally I think the .NET designers simply avoided the issue out of the idea that they had more important concerns to address first. I doubt it was a philosophical decision to make two items which are identical in memory incompatible just because the definitions of those types are contained in different places (leading to different fully qualified names), unlike the decision to avoid multiple inheritance (except that it is support for interfaces...)

Well, sure, they didn't *make* them incompatible (except indirectly), but the critical difference with C++ is that it would have required actual *work* (instead of just aligning things a bit and having it fall into place by virtue of the object layout, like the C++ developers could do -- things are more flexible there).

The objects aren't "identical in memory". The *interfaces* are identical, the objects implementing them presumably are not. The interfaces don't have an in-memory representation, though, except by virtue of the vtable layout (or the CLR equivalent, really). Unlike C++, you'll need to write down when two types are and are not compatible, and the runtime will need to check things before you ever make a call. And yes, they didn't actually build a system that included marshalling by signature.

I'd say it's no so much avoiding the issue as it is thinking that the system they came up with sufficed. You're right inasmuch that the words "plugin system" probably didn't come up during the design phase, though, or they would have made some accommodations (matching up types is just one of the problems; unloading plugins is another one of those things).

--
J.
.



Relevant Pages

  • Re: [Q] superfluous ids in self-referential typedef struct
    ... > anything about the identifier. ... so as a result all compilers now can be and typically are. ... design a language that doesn't do this and successfully compile it -- ... Using C++ only avoids the keyword 'struct', ...
    (comp.lang.c)
  • Re: Wrapping a C++ library using ?FFI
    ... I suspect that for inheritance, the generated code will need to be more dynamic in that the cast_to_base function will need to do some sort of table lookups. ... And C++ template instantiation has enough bugs in real compilers that I don't trust any binding tool to get this completely bug-compatible with any ... Taking the CFFI approach and implementing the ABI in Lisp isn't particularly brittle; it just takes more work to set up (esp. ...
    (comp.lang.lisp)
  • Re: good c compiler
    ... software that compiles under MSVC. ... There are valid reasons for doing this and these apply to closed source libraries as well as open source code. ... For all I know unlike with some other compilers you provide no compatibility with libraries built with MSVC, I just assumed your users might want to be able to use third-party pre-built libraries, since I know that I do, and in that case they need to be aware of any compatibility issues. ...
    (comp.lang.c)
  • Re: usual nontechnical issues
    ... interest from MS in making compatibility complete). ... apps without spending an extra penny than Delphi Standard doesn't seem to ... players now might change when smaller players offer more cost-effective ... > of a bunch of 3rdparty compilers. ...
    (borland.public.delphi.non-technical)
  • Re: Statement on backwards compatibility?
    ... If we upgrade our machines to the latest ... OS, and also the latest compilers, the critical issue is that there will ... be compatibility issue when the compilation takes place on the newer OS ... but then you're taking advantage of backward ...
    (microsoft.public.win32.programmer.kernel)