I have de-compiled some old code from a legacy VB.NET app using ILSply and this line has appeared:
Operators.ConditionalCompareObjectEqual(safeDataReader["isLoader"], -1, false)
I'm aware this is compiler generated, but its not advised that this code is used in application source code. My question is why is this the case and what should it be in 'normal' code?
The documentation for the method says it right there:
Represents the overloaded Visual Basic equals (=) operator.
Why? I don't "know", but it's easy to make an educated guess.
The semantics of the "=" operator in VB.NET are just a bit different from those of C# and the standard Object.Equals(). The semantics are inherited from VB6 and cannot be changed for backward compatibility reasons. Obviously this method implements the VB6 semantics for the compiler.
It would make an interesting read to come up with a systematic analysis of the differences.
Further thoughts:
The reason it's "not recommended" is because there is no reason to call the method from VB.NET: just use =. In C#, there is no particular reason to invoke the VB6 semantics so the method doesn't make a lot of sense there either.
Obviously, if you are compiling C# code generated from VB.NET, then those are special circumstances: calling the method is the right thing to do, unless you're willing to take the time to analyze the code and prove to yourself that the standard = cn be substituted safely.
Related
I'm using NUnit to verify some code and have a problem reporting helpful information. My tests go something along the following lines:
Assert::IsTrue(myClassInstance.SomeMethodToTest(), "Test failed: {0}", myClassInstance.LastError);
The problem is that the LastError property is evaluated before the method is tested so the last error is blank.
Is there any way to delay the evaluation of the last error to give the function some more meaningful output?
Well, that's a big bummer, but you are invoking Undefined Behavior here. NUnit was originally designed for Java, ported pretty well to C# and VB.NET. Languages that promise strict left-to-right function argument evaluation order in their language spec. So that Assert.IsTrue() method has well defined behavior in those languages.
But not in C++/CLI, it takes advantage of the UB rule in C++. No doubt inspired by the [ParamArray] for the 3rd argument, it first polishes off that one before evaluating the other arguments. You get right-to-left order. Shooting off the hip, I'd say that this has something to do with varargs emulation.
Not so sure what to recommend, sailing around UB is forever tricky. You can technically provide your own overloads of Assert::IsTrue() with one or more Object^ arguments. The compiler will pick those instead of the [ParamArray] overload. Or avoid the [ParamArray] overload completely and use String::Format() to generate the message argument instead. You'll now get left-to-right. That's still UB however, it looks okay but I can't promise this will work with every possible set of argument expressions.
Ouch, sorry.
I am going back to school where we have to take a C++ class.
I am familiar with the language but there's a few things I have never heard of...
Generally, my teacher said that plain C++ is "unsafe". It generates "unsafe code" (whatever that means). That's why we have to use C++/CLI which is supposed to make "safe" code.
Now... isn't CLI just a Microsoft .NET extension?
He is also telling us to use Console::WriteLine() instead of cout. Since Console::WriteLine() is "safe" and cout is "unsafe".
All this seems weird to me... Can anyone clarify this?
Thanks!
To put it very blunt and simple.
Safe
By "safe code" you teacher probably means managed code. That is code where you don't have to "care" about pointers and memory, you have a garbagecollector that takes care of this for your. You are dealing with refrences. Examples of languages built like this is java and c#. Code is compiled to a "fictional" opcodes(intermediate language, IL for C#), and compiles and run realtime(JIT, just in time compilation). The IL generated code, will have to be converted to real native platform based opcodes, in java this is one of things the jvm does. You may easily disassemble code from languages like these. And they may run on several platforms without a recompilation.
Unsafe
By "unsafe code" the teacher means ordinary native c++ unmanaged code, where all memory and resource management is handled by you. This makes room for human error, and memory leaks, resource leaks and other memory errors, you don't usually deal with in managed languages. It also compiles to pure bytecode (native assembly opcodes), which means that you have to compile your code for each platform you intend to target. You will encounter that you will have to make a lot of code specific for each platform, depending on what you are going to code. It's nice to see that simple things such as threading, which where platform dependent, now is a part of the c++ standard.
Then you have c++/CLI, which basicly is a mix. You may use managed code from the .net framework in c++, and it may be used as a bridge, and be used to make wrappers.
Console::WriteLine() is managed .net code, safe.
cout is standard iso c++ from <iostream>, unsafe
You find a related post here, with a broader answer here and here :)
Edit
As pointed out by Deduplicator below this is also of interest for you
Hope it helps.
Cheers
In the world of .NET, "safe" is synonymous with "verifiable" type safety. In Visual C++, it's enabled by /clr:safe.
/clr:safe will prevent you from using std::cout or any other function or type implemented in native code, because the metadata needed by .NET's verifier does not exist for native functions. MSIL which Stigandr mentioned can be used for just-in-time compilation, but even when compilation to native code is performed ahead of time, the MSIL is provided alongside the compiled native code and serves as a proof of its type safety which the verifier inspects.
Standard (native / unmanaged) C++ does check type safety during compilation. But that can be disabled by casts, and without runtime type checks, which C++ does not provide as part of the language, pointer arithmetic (e.g. array index out of bounds) can also violate type safety, as can using pointers to freed objects. C++ isn't just a language though, it is also a standard library, where you find smart pointers and smart collections that do the necessary runtime checks, so it can be just as type-safe as any managed framework.
The VB.NET Static declaration:
http://msdn.microsoft.com/en-us/library/z2cty7t8.aspx
The only reference I can find to this question is from 2008:
http://forums.asp.net/t/951620.aspx?what+is+the+equivalent+of+static+from+vb+net+in+c+
Is there an equivalent in recent versions of C#, or still not present? Is there anything particularly wrong about using Static in VB.NET?
C# does not support it and probably won't be because it somehow violates object programming idea of state being part of object, not a method.
Of course one can say that it is only syntactic sugar, and he/she will be event quite right. But still, looking through class code, we expected description of its state variables as a fields of class. Otherwise we should find for it in each and every method.
So this can be simply seen about some high-level decision and your millage may vary here.
Personally, I like the VB procedure-level Static, even if it's not "pure" enough for some folk.
You can set it in declaration and forget it:
Static oClient As HttpClient = New HttpClient()
There's no checking whether a module-level variable needs to be instantiated or not:
If moClient Is Nothing Then moClient = New HttpClient()
And, silly me, I always expect that there is equivalency between C#.NET and VB.NET but I've learned that clinging to that concept is folly, unfortunately.
I have a DLL from a vendor that I Need to invoke from C#. I know that C# data classes are not directly compatible with C++ data types.
So, given that I have a function that receives data and returns a "string".
(like this)
string answer = CreateCode2(int, string1, uint32, string2, uint16);
What must I do to make the input parameters compatible, and then make the result string compatible?
Please - I have never done this: Don't give answers like "Use P/Invoke" or "Use Marshal" I need a tutorial with examples.
All the P/Invoke examples I have seen are from .NET Framework 1.1, and Marshall (without a tutorial) is totally confusing me.
Also, I have seen some examples that tell me when I create my extern function to replace all the datatypes with void*. This is makes my IDE demand that I use "unsafe".
This isn't quite a tutorial but it's got a lot of good information on using P/Invoke
Calling Win32 DLLs in C# with P/Invoke
It'll give you an idea of the terminology, the basic concepts, how to use DllImport and should be enough to get you going.
There's a tutorial on MSDN: Platform Invoke Tutorial.
But it's pretty short and to be honest the one I've mentioned above is a much better source of information, but there's a lot of it on there.
Also useful is the PInvoke Signature Toolkit, described here .
And downloadable here.
It lets you paste in an unmanaged method signature, or struct definition and it'll give you the .NET P/Invoke equivalent. It's not 100% perfect but it gets you going much quicker than trying to figure everything out yourself.
With regards to Marshalling specifically, I would say start simple.
If you've got something that's some sort of pointer, rather than trying to convert it directly to some .NET type in the method signature using Marshal it can sometimes be easier to just treat it as an IntPtr and then use Marshal.Copy, .PtrToString, .PtrToStructure and the other similar methods to get the data into a .NET type.
Then when you've gotten to grips with the whole thing you can move on to direct conversions using the Marshal attribute.
There's a good 3 part set of articles on marshalling here, here and here.
I need to work on converting a very huge c++ project to clr safe. The current c++ project has a lot of stuff from c++ like templates, generics, pointers, storage/stream, ole apis, zlib compression apis, inlines etc. Where can I find the datiled document for this type of conversion? Can you suggest some good book to refer to? If anyone of you have done such conversion, can I get some analysis from you?
I'll just cough up the MSDN Library article titled "How to: Migrate to /clr:safe
Visual C++ can generate verifiable components with using /clr:safe, which causes the compiler to generate errors for each non-verifiable code construct.
The following issues generate verifiability errors:
Native types. Even if it isn't used, the declaration of native classes, structures, pointers, or arrays will prevent compilation.
Global variables
Function calls into any unmanaged library, including common language runtime function calls
A verifiable function cannot contain a static_cast Operator for down-casting. The static_cast operator can be used for casting between primitive types, but for down-casting, safe_cast or a C-Style cast (which is implemented as a safe_cast) must be used.
A verifiable function cannot contain a reinterpret_cast operator (or any C-style cast equivalent).
A verifiable function cannot perform arithmetic on an interior_ptr. It may only assign to it and dereference it.
A verifiable function can only throw or catch pointers to reference types, so value types must be boxed before throwing.
A verifiable function can only call verifiable functions (such that calls to the common language runtime are not allowed, include AtEntry/AtExit, and so global constructors are disallowed).
A verifiable class cannot use Explicit.
If building an EXE, a main function cannot declare any parameters, so GetCommandLineArgs must be used to retrieve command-line arguments.
Making a non-virtual call to a virtual function.
Also, the following keywords cannot be used in verifiable code:
unmanaged and pack pragmas
naked and align __declspec modifiers
__asm
__based
__try and __except
I reckon that will keep you busy for a while. There is no magic wand to wave to turn native C++ into verifiable code. Are you sure this is worth the investment?
The vast majority of native C++ is entirely valid C++/CLI, including templates, inlines, etc, except the CLR STL is rather slow compared to the BCL. Also, native C++ doesn't have generics, only templates.
The reality of compiling as C++/CLI is to check the switch and push compile, and wait for it to throw errors.
Rewriting native C++ into safe C++/CLI will result in a code that is syntactically different, but semantically same as C#. If that is the case, why not rewrite directly in C#?
If you want to avoid what is essentially a complete rewrite, consider the following alternatives:
P/Invoke. Unfortunately, I'm unfamiliar whether this would isolate safe from unsafe code. Even if it can perform the isolation, you'll need to wrap your existing C++ code into procedural, C-like API, so it can be consumed by P/Invoke. On a plus side, unless your API is excessively chatty, you get to keep (most of) your native performance.
Wrapping your C++ into out-of-process COM server and using COM Interop to consume it from the manged code. This way, your managed code is completely protected from any corruption that might happen at C++ end and can remain "safe". The downside is a performance hit that you'll get for out-of-process marshaling and the implementation effort you'll need to expend to correctly implement the COM.