In my own program I'm trying to use this code here to add tooltip balloon windows to my application: http://www.codeproject.com/Articles/4991/Balloon-Tips-Galore (Source code available here)
I tried compiling the demo program and it works fine on 32-bit Windows 7, but when I try to use it on 64-bit Windows 7 the program crashes. If I try to debug the crash in VS2010 I get this message:
The debugger is in some area where the source code isn't available and it says Call stack location: ntdll.dll!0000000076fe40f2()
How can I fix this so it won't crash on 64-bit?
I can't make the C# demo crash on Windows Server 2003 x64 (which is the only 64-bit environment I have handy at the moment), but the code is faulty so it makes sense that you're seeing unexpected behavior.
Edit: Reproduced the crash in Windows Server 2008 R2 x64 using the original code, and verified the efficacy of the fix.
As Christian.K points out, the problem has been noted before. When calling the Marshal.StructureToPtr method, you should pass true for the third fDeleteOld parameter only when the specified memory block does not contain valid data. This is called out pretty explicitly in the documentation, so I'm not sure how the original writer got it wrong.
In this case, since the data was just allocated the line before by calling Marshal.AllocHGlobal, it does not contain valid data and should not be deleted/freed. The change is simple: change the third parameter true to false. Unfortunately, because the interop code is scattered across three different classes in the sample project, you'll have to make the change multiple places. The pattern you're looking for is this:
IntPtr ptrStruct = Marshal.AllocHGlobal(Marshal.SizeOf(ti));
Marshal.StructureToPtr(ti, ptrStruct, false /* <-- change this from true to false */);
Just as a general observation: the code tries to handle a lot of the interop stuff manually (by using methods of the Marshal class) rather than just letting the CLR handle it automatically. I much prefer the latter method. Even though I fully understand how to do all of the interop manually, letting the system manage it for me keeps down the number of mistakes I make and resulting heap corruption.
RhysW says he's never encountered heap corruption before, but it becomes very common when you start doing interop between .NET code and the Win32 API. The .NET Framework is no longer protecting you.
For an example of what I mean, notice that the FMSBalloonTip.SetToolTip method uses the Marshal.StringToHGlobalAuto method to marshal the string containing the tooltip's title as a pointer. While that certainly works (and the author was thankfully careful to free the pointer after they're finished), it would be much easier and less error-prone to declare an overload of the SendMessage function that accepts a string object as the fourth parameter. That way, the framework will handle all of the necessary interop stuff for you transparently.
The real question, of course, is why you need this code at all. It's way easier to just use the built-in ToolTip class, which has been available since the beginning. I'm not sure if you just didn't mention some feature you need that ToolTip doesn't provide or you just don't know about it, but I strongly recommend reconsidering your design so that you can make use of the built-in class and let the Microsoft programmers handle all of the interop stuff.
If it's the balloon part you're looking for, make sure to set the IsBalloon property of the ToolTip class. That wasn't introduced until .NET 2.0, but that's the same version the sample project is targeting.
Related
I need to use both C# and C++ in my OpenGL project. Ideally, the entire project is written only in C# using OpenTK (OpenGL functions ported to C#), GLFW.NET (aka ported GLFW), and GlmNet (GLM).
There's only one tiny place where I have to dynamically create an OpenGL texture using libraries that are only available for C++. In idea, this is not supposed to be a problem:
(make a DLL and use it in C#)
//In C++, Create DLL API for C# to use:
extern "C" MYDLL_API unsigned int GenerateTexture();
//in C#, bind an existing DLL.
[DllImport("MYDLL.dll", EntryPoint = "GenerateTexture", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern uint GenerateTexture();
This function should generate texture inside, set its bitmap and properties, and then return the handle of this texture. Spoiler - it immediately fails:
//C++. inside of a function GenerateTexture:
//(by the way, if that's important, on the side of C++, i use 'glad')
unsigned int texture;
glGenTextures(1, &texture);
^^^ sets texture to 0
glBindTexture(GL_TEXTURE_2D, texture);
^^^ throws access violation exception
I have googled about this issue and apparently, it's because OpenGL context is absent.
I have Glfw and OpenGL contexts all successfully initialized in C#, all functions are usable and workable. DLL itself is perfectly callable and I can even debug it. And everything is happening in one single thread.
Then why I cannot create a texture from a DLL?
first thought: maybe context is not magically passed to the DLL?
I searched how to pass the OpenGL context to the DLL, but everybody says when DLL is used, it becomes a part of the project, therefore context is automatically applied. OpenGL context is theoretically present in DLL.
Who or what fools me then?
A little handy problem-localizing test for you guys:
//Let's try creating a texture in C# itself
//right in the place where DLL is called
uint texture = glGenTexture();
^^^ returns a workable identifier 1.
uint textureFromDLL = DLL.GenerateTexture();
^^^ access violation.
So here it is apparent that the actual problem is that only this DLL is the one who cannot access OpenGL functions.
I have no idea what to think in this situation, maybe C#'s OpenTK and C++'s glad are wrapping different OpenGLs?:) it makes no sense to me. or, maybe people were wrong saying that openGL context is automatically present in DLL. In this case, my question is how can i transfer this almighty yet occult context to my pathetic DLL.
I tried to create and bind a texture in C#, and right after it, pass a handle to this texture to the DLL. but everything's futile, it throws access violation exception right on the next command where i call glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT). so yet again it needs full context, not just a handle.
Yes, I could rearrange the function so that C++ part does only the thing that has nothing to do with OpenGL. But it stresses me that something doesn't work when it theoretically should, and I'm afraid i will have serious problems if i need more DLL functionality in the future.
If someone needs to know it, my DLL is right inside the project, in Debug and Release folders. I use Visual Studio, C++20 (latest), C# .NET Core 3.1.
The answer. First theoretical part and below the actual steps to solve it.
I guess I'm not going to be the only person facing such an issue so this is a comprehensive answer for other people, based on my current experience.
Within one thread, OpenGL context holds, even while calling DLL.
Then why did access violation happen to me?
My assumption was that OpenGL function is being called, then inside, graphics driver tries to work on it and tries to access an existing OpenGL context in memory. If i didn't initialize OpenGL, it attempts to access memory that is not allocated, hence access violation exception occurs.
Well... The thing is... In reality, driver does not fail at all, because it's not even called! Turns out DLL was not even bound to the OpenGL functions to call them!
Actually, the C# situation is no different. neither of the functions are defined by default, they need to be bound dynamically, and I have the needed call Import(Glfw.GetProcAddress); in C# code. Without it, C# throws NullReferenceException when i call any OpenGL function.
And C++'s 'glad' is the same. All of the functions are just declarations which are function pointers to the actual driver functions, they need to be dynamically connected. Without it, these functions are pointing to nowhere.
They point to nowhere, therefore access violation error occurs. Again, context is here, it keeps its existence in DLL. The only thing needed is to make OpenGL function pointers valid in my C++ code too.
Holy user with the name 'BDL' precisely mentioned this idea in the comments with a suggestion to use gladLoadGLLoader in C++ to initialize glad.
I searched for some information about this function and its usage seems a little tricky: I have to pass some GLADloadproc which i have access to only in C#. While searching for how to accomplish it, i found a neighbouring 'glad' function gladLoadGL() which doesn't require any parameters to be passed. For a simple case like mine, this function is enough to initialize everything. And this is it! The easy function which truly solved my problem.
Actual Steps
If you have this exact situation where you want to occasionally access OpenGL functions from the DLL, just add a new function to your DLL, call it something like "Initialize":
//C++
void Initialize() {
gladLoadGL();
}
while in C#: (i guess it can be any other language, like Java, why not)
//right after you have initialized everything in C#
DLL.Initialize(); //initialize C++ part too.
You call it once. After it DLL is perfectly workable. Now everything is initialized in C# and everything is initialized in C++ codebase too. After this, you will be able to use OpenGL functions freely throughout the program and its DLL-s.
If that doesn't work, then I sincerely apologize for taking your time, it means the issue is yet again caused by something different.
You load a foreign code example with libraries attached to it in Visual Studio. Now there is a method that you want to reuse in your code. Is there a function in VS that lets you strip the code from all unnecessary code to only have code left that is necessary for your current method to run?
It is not about the library. Loading a .sln or .csproj and having classes over classes when you just want one method out of it is a waste of performance, ram and space. It is about code you can easily omit or references(what I call libraries) you can easily omit. A part-question of this is: Which "using" statement do you need that is only necessary for your current method and the methods that pass paramaters to it? In short, showing relevant code only. Code that is tied to each other.
Let's use an example: You go to github and download source code in c#. Let's call the solution S. You open S in Visual Studio. You don't disassemble, you just load the source code of S, that is there in plain text. Then you find a method M - in plain text - that you want to use. M contains some objects whose classes were defined somewhere in the project. The goal is to recreate the surrounding only for this method to copy & paste it into my own solution without having red underlined words in almost every line within the method
after reading the question and the comments, I think I have a vague idea what you are referring to.
In case we ignore the context of the method you are referring, you can extract any code piece from a "library" by using a .NET decompiler and assembly browser.
There are many of them for free, such as:
dotPeek,
ILSpy
...
This will allow you to see the method's code. From there on, you can proceed as you like. In case your copy the method to your code base, you might still have to change it a bit in order to adapt it to work with your objects and context. If you don't, this will give you insight on how the method works and might help you to understand the logic, so you can write your own.
Disclaimer: With this post, I am pointing out that it is possible to extract code from an assembly. I am not discussing the ethics or legal perspective behind such actions.
Hope this helps,
Happy Coding!
If it`s just one method, look at the source code and copy it to your libarary. Make sure you make a comment where you obtained the code and who has the copyright! Don't forget to include the licence, which you should have done with a libary reference anyway.
That said it is currently not (official) possible to automaticly remove unused public declared code from a library (assembly). This process is called Treeshaking by the way. Exception: .NET Native.
But .NET Native is only available for Windows Store Apps. You can read more about it here.
That said, we have the JIT (Just in Time)-Compiler which is realy smart. I wouldn't worry about a few KB library code. Spend your time optimizing your SQL Queries and other bottlenecks. The classes are only loaded, when you actualy use them.
Using some unstable solutions or maintaining a fork of a library, where you use more then one method (with no documentation and no expertise, since it is your own fork) isn't worth the headache, you will have!
If you realy want to go the route of removing everything you do not want, you can open the solution, declare everything as internal (search and replace is your friend) and restore the parts to public, which are giving you are Buildtime error / Runtime error (Reflection). Then remove everything which is internal. There are several DesignTime tools like Resharper, which can remove Dead Code.
But as I said, it's not worth it!
For .NET Core users, in 6-8 weeks, we have the .NET IL Linker as spender has commented, it looks promising. What does this mean? The .NET framework evolves from time to time. Let it envolve and look at your productivity in the meantime.
I've come across what I think is an interesting bug in iOS 5.0 (this code works perfectly in 5.1). After ages of narrowing it down using lots of Console.Write()'s, I narrowed the crash to:
nsUrl.ToString();
This is either in the MonoTouch library or iOS.
Anybody else come across this? It's annoying, as we obviously want to support the minimum iOS version possible.
In MonoTouch the default ToString implementation, for NSObject subclasses, is to call the description selector.
In some cases (and yes it varies with iOS versions) calling description can fail (or even crash the process). That generally occurs when the native object is a bad state (e.g. mis-initialized, invalid value...).
MonoTouch tries to handle such cases (when possible and known) by using a different ToString implementation (e.g. with extra checks or by falling back to the default ToString, which returns the type name).
Note: If you find such behaviour please report them in bug reports and we'll see if they can be handled differently.
Considering this question of SO, where whole C# in-memory compiler is being called. When only lexical and syntactic analyzing is required: parse text as a stream of lexemes, check them and exit.
Is it possible in current version of System.CodeDom.Compiler, if not - will it be?
If you can use Mono, I believe it has a C# parser/lexer you may be able to use.
Here's a link to look into. As for what the MS C# team is planning to do, there is some talk of at some point making the C# compiler into a "service" - but it's unclear what that means or when that will happen.
While it might look like the code is compiled in-memory (CompilerParameters.GenerateInMemory), that's not what actually happens. The same compiler as the one used in Visual Studio is used to compile the code (csc.exe). It gets started by CreateProcess (much like Process.Start) and runs out-of-process to compile the code to an assembly on disk in a temporary folder. The GenerateInMemory option invokes Assembly.LoadFrom() to load the assembly.
You'll get the equivalent of a syntax check simply by setting GenerateInMemory to false and delete the OutputAssembly after it is done.
While this might sound kinda backwards, the huge benefit it has is that this won't put any memory pressure on your process. This will hold you over until C# 5.0 ships.
I have a small to medium project that is in C++/CLI. I really hate the syntax extensions of C++/CLI and I would prefer to work in C#. Is there a tool that does a decent job of translating one to the other?
EDIT: When I said Managed c++ before I apparently meant c++/CLI
You can only translate Managed C++ code (and C++/CLI code) to C# if the C++ code is pure managed. If it is not -- i.e. if there is native code included in the sources -- tools like .NET Reflector won't be able to translate the code for you.
If you do have native C++ code mixed in, then I'd recommend trying to move the native code into a separate DLL, replace your calls to DLL functions by easily identifiable stub functions, compile your project as a pure .NET library, then use .NET reflector to de-compile into C# code. Then you can replace the calls to the stub functions by p-invoke calls to your native DLL.
Good luck! I feel for you!
.NET Managed C++ is like a train wreck. But have you looked into C++ CLI? I think Microsoft did a great job in this field to make C++ a first class .NET citizen.
http://msdn.microsoft.com/en-us/magazine/cc163852.aspx
I'm not sure if this will work, but try using .Net Reflector along with ReflectionEmitLanguage plug-in. The RelelectionEmitLanguage plug-in claims to convert your assembly to c# code.
It has to be done manually unfortunately, but if the code is mostly C++/CLI (not native C++) then it can actually be done pretty quickly. I managed to port around 250,000 lines of C++/CLI code into C# in less than a couple of months, and I don't even know C++ very well at all.
If preserving Git history is important, you might want to git mv your cpp file into a cs file, commit, then start porting. The reason for this is that Git will think your file is new if you modify it too much after renaming it.
This was my approach when porting large amounts of code (so that it wouldn't take forever):
Create another worktree / clone of the branch and keep it open at all times
This is extremely important as you will want to compare your C# to the old C++/CLI code
Rename cpp to cs, delete header file, commit
I chose to rename the cpp file since its git history is probably more important than the header file
Create namespace + class in cs file, add any base classes/interfaces (if abstract sealed, make static in C#)
Copy fields first, then constructors, then properties, and finally functions
Start replacing with Ctrl+H:
^ to empty
:: to .
-> to .
nullptr to null
for each to foreach
gcnew to new
L" to "
Turn on case sensitivity to avoid accidental renames (for example L"cool" should become "cool", not "coo"
Prefixes like ClassName:: to empty, so that MyClass::MyMethod becomes MyMethod
Go through the red code and port manually code that cannot be just replaced (e.g. some special C++ casts), unless you have some cool regex to do it fast
Once code compiles, go through it again, compare to C++/CLI line by line, check for errors, clean it up, move on.
If you encounter a dependency that needs to be ported, you could pause, port that, then come back. I did that, but it might not be so easy.
Properties were the most annoying to port, because I had to remove everything before and after the getters and setters. I could have maybe written a regex for it but didn't bother doing so.
Once the porting is done, it's very important that you go through the changes line by line, read the code, and compare with C++/CLI code and fix possible errors.
One problem with this approach is that you can introduce bugs in variable declarations, because in C++/CLI you can declare variables in 2 ways:
MyType^ variable; <- null
MyType variable; <- calls default constructor
In the latter case, you want to actually do MyType variable = new MyType(); but since you already removed all the ^ you have to just manually check and test which one is correct. You could of course just replace all ^'s manually, but for me it would have taken too long (plus laziness) so I just did it this way.
Other recommendations:
Have a dummy C++/CLI project and a tool like LinqPad or another C# project to test differences between C++/CLI and C# if you're unsure of a piece of ported code
Install Match Margin to help highlight similar code (helped me when porting WinForms code)
ReSharper! It helped with finding bugs and cleaning up the code a LOT. Truly worth the money.
Some gotchas that I encountered while porting:
Base classes can be called in C++/CLI like so: BaseClass->DoStuff, but in C# you would have to do base.DoStuff instead.
C++/CLI allows such statements: if (foo), but in C# this has to be explicit. In the case of integers, it would be if (foo != 0) or for objects if (foo != null).
Events in base classes can be invoked in C++/CLI, but in C# it's not possible. The solution is to create a method, like OnSomeEvent, in the base class, and inside that to invoke the event.
C++/CLI automatically generates null checks for event invocations, so in C# make sure to add an explicit null check: MyEvent?.Invoke(this, EventArgs.Empty);. Notice the question mark.
dynamic_cast is equivalent to as cast in C#, the rest can be direct casts ((int) something).
gcnew can be done without parentheses. In C# you must have them with new.
Pay attention to virtual override keywords in the header files, you can easily forget to mark the C# methods with override keyword.
Intefaces can have implementations! In this case, you might have to rethink the architecture a bit. One option is to pull the implementation into an abstract class and derive from it
Careful when replacing casts with Convert calls in C#
Convert.ToInt32 rounds to the narest int, but casting always rounds down, so in this case we should not use the converter.
Always try casting first, and if that doesn't work, use the Convert class.
Variables in C++/CLI can be re-declared in a local scope, but in C# you get naming conflicts. Code like this easily lead to hard to find bugs if not ported carefully.
Example: An event handler can take a parameter e, but also has a try-catch like catch (Exception e) which means there are 2 e variables.
Another example:
// number is 2
int number = 2;
for (int number = 0; number < 5; number++)
{
// number is now 0, and goes up to 4
}
// number is again 2!
The above code is illegal in C#, because there is a naming conflict. Find out exactly how the code works in C++ and port it with the exact same logic, and obviously use different variable names.
In C++/CLI, it's possible to just write throw; which would create a generic C++ exception SEHException. Just replace it with a proper exception.
Be careful when porting code that uses the reference % sign, that usually means that you will have to use ref or out keywords in C#.
Similarly, pay attention to pointers * and & references. You might have to write additional code to write changes back whereas in C++ you can just modify the data pointed to by the pointer.
It's possible to call methods on null object instances in C++/CLI. Yes seriously. So inside the function you could do If (this == null) { return; }.
Port this type of code carefully. You might have to create an extension method that wraps over this type of method in order to avoid breaking the code.
Check and make sure everything in the old project file vcxproj was ported correctly. Did you miss any embedded resources?
Careful when porting directives like #ifdef, the "if not" (#ifndef) looks awfully similar but can have disastrous consequences.
C++/CLI classes automatically implement IDisposable when adding a destructor, so in C# you'll need to either implement that interface or override the Dispose method if it's available in the base class.
Other tips:
If you need to call Win32 functions, just use P/Invoke instead of creating a C++/CLI wrapper
For complex native C++ code, better create a C++/CLI project with managed wrappers
Again, pay attention to pointers. I had forgotten to do Marshal.StructureToPtr in my P/Invoke code which wasn't necessary in the C++ version since we had the actual pointer and not a copy of its data.
I have surely missed some things, but hopefully these tips will be of some help to people who are demoralized by the amount of code that needs to be ported, especially in a short period of time :)
After porting is done, use VS/ReSharper to refactor and clean up the code. Not only is it nice for readability, which is my top priority when writing code, but it also forces you to interact with the code and possibly find bugs that you otherwise would have missed.
Oh and one final FYI that could save you headaches: If you create a C++/CLI wrapper that exposes the native C++ pointer, and need to use that pointer in an external C++/CLI assembly, you MUST make the native type public by using #pragma make_public or else you'll get linker errors:
// put this at the top of the wrapper class, after includes
#pragma make_public(SomeNamespace::NativeCppClass)
If you find a bug in the C++/CLI code, keep it. You want to port the code, not fix the code, so keep things in scope!
For those wondering, we got maybe around 10 regressions after the port. Half were mistakes because I was already on autopilot mode and didn't pay attention to what I was doing.
Happy porting!
Back ~2004 Microsoft did have a tool that would convert managed C++ to C++/CLI ... sort of. We ran it on a couple of projects, but to be honest the amount of work left cleaning up the project was no less than the amount of work it would have been to do the conversion by hand in the first place. I don't think the tool ever made it out into a public release though (maybe for this reason).
I don't know which version of Visual Studio you are using, but we have managed C++ code that will not compile with Visual Studio 2005/2008 using the /clr:oldSyntax switch and we still have a relic VS 2003 around for it.
I don't know of any way of going from C++ to C# in a useful way ... you could try round tripping it through reflector :)
Such projects are often done in c++/cli because C# isn't really an elegant option for the task. e.g. if you have to interface with some native C++ libraries, or do very high performance stuff in low level C. So just make sure whoever chose c++/cli didn't have a good reason to do it before doing the switch.
Having said that, I'm highly skeptical there's something that does what you ask, for the simple reason that not all C++/cli code is translatable to C# (and probably vice versa too).