I can't reference ImageSearch.dll in my project. I've been trying for days and can't get any further. it seems to me that i'm the only one with this problem and i don't know what to do next. Is it possible to reference a .dll manually, for example via lines of code? It's nerve wracking and need this or a similar feature.
I keep getting the following error:
Could not add a reference to imagesearch.dll. Make sure the file is accessible and is a valid assembly or COM component.
enter image description here
Hope someone can help me...
That message is telling you that the dll you're trying to reference is something that .NET doesn't know how to work with automatically. This means it has no idea what functions are in the dll or how they work. So, if a dll isn't a .NET assembly or exposed via COM, then you can use PInvoke (Platform Invoke).
Don't add the dll as a reference to your project at all, instead add it as a content file that gets output with the rest of your compiled code. Getting PInvoke to work with an arbitrary DLL can be quite complicated, so be prepared for some headaches. There's an entire website with examples of how to pinvoke for all sorts of libraries at http://pinvoke.net/ that will give you lots of ideas.
Then you can call methods in the dll by doing something like:
// Import ImageSearch.dll (containing the function we need) and define
// the method corresponding to the native function.
[DllImport("ImageSearch.dll"]
private static extern int FindImage(string imagePath);
Obviously I have no idea what imagesearch.dll is or does, so I have no idea what the actual PInvoke function should look like, you'll have to figure that out from the dll's interface.
https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke
I have two apps -- a C# app and a VBA app. I would like to create a variable in each app that points to the same memory location. The intent is, if I change the value in one app, the other app immediately has access to that value without any additional logic to transfer that data between the apps. In essence, I want to "remotely control" the value of the C# variable from a VBA app.
I'm not sure if this is even possible, so any help is greatly appreciated.
EDIT: I am considering a slightly different approach, now. I may use a non-persistent Memory Mapped File to transfer the data between the two apps. Although some code would be required to write/read the memory-mapped file, it is better than disk i/o. I am transferring a real number between the two apps (e.g. 1.2345). Not sure which class to use -- StreamWriter, StringWriter or TextWriter? Any suggestions??
Thank you.
You will need to pass the variable by reference to your code in C#
While I have not tried this directly in C#, the C++ equivalent of what you're looking for is given below. Do note that this approach uses global variables and is very crude and potentially unsafe, so be very careful with dealing with memory this way. I am sure there might be more elegant ways to express this.
double* monitored_variable_global_pointer;
void __stdcall DoSomething(double &monitored_variable)
{
// since monitored_variable is passed by reference, any change here, will change it on the VBA side, e.g.
monitored_variable_global_pointer = &monitored_variable;
}
// On the VBA side, the passed variable will have to be global too for this to work.
// Also, you need the function calling convention to be stdcall for it to work with VBA, at least when making functions in C++
Once the code is written,
The C++ code is compiled into a DLL
The function is then called once in VBA (preferably triggered by the event that the workbook is opened, after declaration of the global variable)
You would need to do the equivalent of these steps in C# for achieving the desired effect.
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.
What can be done to speed up calling native methods from managed code?
I'm writing a program which needs to be able to manage arbitrarily-sized lists of objects and retrieve information from them at high speed, which it feeds into scripts. Scripts are bits of compiled C# code. I'm writing a basic interface layer from the C++ (native) DLL/SO/etc to the C# (.Net or Mono) management layer.
Now, I've been doing some testing, and I've found that on average, PInvoking a native method from managed code is something like 100 times slower than doing it all in managed (all native and all managed are identically fast, for reference).
The syntax I was using is:
[DllImport("test.dll")]
extern static public String test_method(String value);
String returnedValue = test_method("hello world");
Is there a way to cache a pointer to the function, some code of fast invoker, that would increase speed after loading the native library? That would solve the problem quite neatly, so I doubt it exists. :P
Edit: I didn't specify, but this needs to work on Windows, Linux (Ubuntu at least) and Mac OS X, all for both x86 and x64. Otherwise I would've gone with a C++/CLI interface and been done with it, but unless that works for all 3 platforms, I can't use it.
Further to my question comment, we've established that it was a debug build with the debugger attached. This has a massive impact on runtime performance of .NET code. Easy mistake to make. :)
I'm guessing with a release build and no debugger attached, the performance difference is now much more reasonable.
If you have a very chatty API, and the native methods being called are cheap, then method call overhead can be a performance issue. Try and design a less chatty API. This is a typical technique used to increase the performance of boundary\systems communications.
If performance is acceptable after sorting the debugger issue, there is a simple technique that I have used to easily get a substantial performance increase in chatty APIs, by just adding a single attribute.
In the classes where you have your imported functions (i.e. the DllImport functions), place the SuppressUnmanagedCodeSecurity attribute on the classes. This will remove some expensive security checking from each P/Invoke call. Please see the documentation on SuppressUnmanagedCodeSecurity to understand the ramifications of this. I tend to keep my imported functions grouped together in internal classes (that only contain imported functions) with this attribute applied.
Perhaps the string marshalling is what is causing a slowdown. For comparison sake, try to profile a function that takes and returns elementary C++ types like int.
You can also try to experiment with C++/CLI. That way you can take explicit control over the marshalling and maybe see an improvement.
In C++/CLI assembly:
System::String ^ test_method(System::String ^ args)
{
pin_ptr<const wchar_t> pp = PtrToStringChars(args);
//This might leak, probably needs a smart pointer to wrap it
wchar_t* ret = native_method(pp);
return gcnew String^(ret);
}
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).