I've recently moved a project I'm working on from .NET 3.5 to .NET 4. I'm using C#, Managed C++ and Unmanaged C++.
In one of my Managed C++ (interop) I'm having a static constructor:
public ref class StaticPool : public BaseStaticPools
{
public:
static StaticPool()
{
InitializePools();
}
static Poolable^ Dequeue()
{
return (Poolable^)Dequeue(Poolable::typeid);
}
private:
static void InitializePools()
{
BaseStaticPools::CreatePool(Poolable::typeid);
}
};
In .NET 3.5 once Dequeue() had been called for the first time it would trigger the static initialization, which runs the static constructor. Once I moved to .NET 4.0, the static constructor was never called.
I know there have been changes in static initializations in .NET 4.0, but according to all I read it should work fine.
In .NET, type initializers may only be called the first time a field is accessed. This is controlled by the [BeforeFieldInit] attribute.
I filed a bug report, which is only available to beta testers, despite being marked "Public".
Here's the explanation from Microsoft, which you may find helpful:
For C++, this is the intended behavior. We mark our classes with BeforeFieldInit, and so the initialization the CLR is performing is correct. We do not offer a way in C++/CLI to change this behavior. If you require the class constructor to run, you are able to call System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor explicitly.
Since we're invoking the standard here, the line from Partition I, 8.9.5 says this:
If marked BeforeFieldInit then the type’s initializer method is executed at, or sometime before, first access to any static field defined for that type.
That section actually goes into detail about how a language implementation can choose to prevent the behavior you're describing. C++/CLI chooses not to, rather they allow the programmer to do so if they wish.
Basically, since the code below has absolutely no static fields, the JIT is completely correct in simply not invoking static class constructors.
Jon Skeet wrote on this topic:
Type initialization changes in .NET 4.0
Related
I use a dll to controll some hardware, and there are two versions of the hardware (and the dll). Some functions have changed, but most of the functions provided by the dll have stayed the same - except that in the newer version, parameters are always provided as Int32, UInt32, and in the old version it was short and ushort.
I created a wrapper class for both versions of the dll that inherits from the dll and provides additional features and masks the functions that acutally did change. By just changing one using, the programm can than be compiled for the old or the new version, and I don't have to write and maintain a big chunk of code twice.
But now I am starting to redefine every function of the dll because of the changed signature like this, which isn't exactly fun:
class ABCWrapper : ABC_V1
{
...
public new static void jump_abs(Int32 x_abs, Int32 y_abs)
{
ABC_V1.jump_abs((short)x_abs, (short)y_abs);
}
...
}
Is there any way to do this automatically, like defining sth. as "Is function inherited from ABC_V1? Yes -> Try explicit cast of parameter" or something?
I want to create a class library project in C# and attach it to a procces.
I've already did this in C++, my code is
#include <windows.h>
void Thread()
{
// here i just do my stuff
}
int WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if(reason==DLL_PROCESS_ATTACH)
{
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Thread, 0, 0, 0);
}
return 1;
}
This works very well for me.
Is possible to do this in C#?
Thanks, I hope i'll find an answer and accept it.
C# doesn't have a mechanism such as DllMain where you can execute code when referenced or used from an executable. The executable will need to explicitly call a method on (or at least use) a type within your library in order for your code to execute.
If you know a type within your library is going to be used, however, you can "cheat" and get your thread to start by placing it within the static constructor for that type. This will cause it to execute at or before the first usage of that type.
That being said, if you're writing the exe that's going to use this C# library, you can just call a method on a type that begins your thread and starts your work.
Follow the discussion here.
Give your class a static constructor and do your initialization there.
It will run the first time anybody calls a static method or property
of your class or constructs an instance of your class.
Soulds like you can use module initializers. Unfortunately C# doesn't support them. You will have to inject the IL, for example using a tool like Module Initializer or Fody
I can call C++ wrapper class from C# via
[DllImport("SomeDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void M();
Where in the C++ code I have
extern "C" { __declspec(dllexport) BSTR GroupTerm(); }
void M() { /* Do Stuff */ }
This works great, however for a number of reasons, I want to include the method M in a class
class SomeClass {
public:
void M();
}
I have tried doing
class SomeClass {
public:
void __declspec(dllexport) M();
}
where
void __declspec(dllexport) SomeClass::M() { /* Do Stuff */ }
But the C# code (using the C# code for import declared above) cannot find the entry point and throws an exception. My question is then, how can I export this method M() [which is a public member of SomeClass for use with interop/pinvoke from C#?
Thanks for your time.
Well there is a few ways, all with different merrits.
One of the more simple is to make a C-wrapper for your C++ class (i'm too lazy to put in the decorations, you should do that yourself).
class SomeClass {
public:
void M();
};
void* MakeSomeClass() {return new SomeClass();}
void DestroySomeClassHandle(void* handle) { delete (SomeClass*)handle;}
void M(void* handle) { ((SomeClass*)handle)->M();}
Then you import the C functions as you normally would.
The upside to this is you don't have to do anything you aren't currently familiar with. Many more things (Matlab, Python, ect) have things similar to PInvoke, so this makes your code much more cross-language usable.
The downside is this is super error prone, and you throw away alot of your type safety.
The better way (imho) is to make a C++/CLI wrapper for the class
public ref class ManageSomeClass
{
public:
ManageSomeClass() {myclass_ = new SomeClass();}
!ManageSomeClass() { if (myclass) {delete myclass; myclass_ = NULL;} }
~ManageSomeClass() { this->!ManageSomeClass(); }
void M() { myclass_->M();}
private:
SomeClass* myclass_;
};
I used SomeClass as a pointer to show the destructor-finalizer, but it doesn't need to be a pointer. It could be a full instance. The big thing is that this will be compiled into a .NET class (in a dll) and you can import it into your C# code. Then the call is:
//c# code
ManageSomeClass msc = new ManageSomeClass();
msc.M();
Upside is the flexibility to go from managed to unmanaged like that. The downside is that you are suddenly maintaining another interface. If you have inheritence/polymorphism, your wrappers have to mirror that structure. This is also a nightmare to maintain.
Edit: Another downside is you have to learn C++/CLI, which is (kindof) and extension of C++ and also (kindof) a completely different language.
The final way is through COM interfaces. http://msdn.microsoft.com/en-us/library/aa645736%28v=vs.71%29.aspx. You can use the same COM import calls you use in C++ in C# (with some minor differences) to instantiate and call COM classes. But you need to learn COM (which I've never done) and then implement your class in a COM complaint way. But then you have a COM interface, which can be imported all over Windows.
Assuming the method is static you have a couple of choices:
Use a tool like Dependency Walker to find out the name under which the function is imported. Use the EntryPoint parameter of DllImport to locate it.
Export the function with a .def file. Then you have total control over the exported name.
Wrap the method in a non-member function and export that.
Frankly, option 3 is the one I would select.
When you get around to member functions you'll need to export functions that accept an instance pointer as their first parameter. And you'll likely have to export functions that instantiate objects.
That said, and responding to your comments, other likely better solutions to your problem are:
Early bound COM, or
A C++/CLI wrapper.
Another method (apart from what #MadScienceDreams and #DavidHeffernan said) is to make your C++ code into a Windows Runtime DLL and then it can be used in your C# code. See here for the details and sample: Creating Windows Runtime Components in C++
Excerpt from the link:
article shows how to use C++ to create a Windows Runtime component,
which is a DLL that's callable from a Windows Store app that's built
by using JavaScript—or C#, Visual Basic, or C++
...
In general, when you code your C++ component, use the regular C++
library and built-in types, except at the abstract binary interface
(ABI) boundary where you are passing data to and from code in another
.winmd package. There, use Windows Runtime types and the special
syntax that Visual C++ supports for creating and manipulating those
types. In addition, in your Visual C++ code, use types such as
delegate and event to implement events that can be fired from your
component and handled in JavaScript, Visual Basic, or C#.
Here is the sample code for "Creating Windows Runtime Components in C++".
I am upgrading an existing VS2008-based C++/CLI project (to be more specific, CefSharp) to VS2012 and am facing some challenges in the meanwhile. To avoid depending on VS2008 for compilation, I have upgraded the project to target the .NET Framework 4.0.
All is well and the project compiles correctly, but when I run it and try to create a WebView instance, I get the following TypeLoadException:
Method 'SetCursor' in type 'CefSharp.Wpf.WebView' from assembly 'CefSharp.Wpf, Version=1.25.0.35385, Culture=neutral, PublicKeyToken=null' does not have an implementation.":"CefSharp.Wpf.WebView"
Obviously, I've examined both the WebView.h and the WebView.cpp quite closely. Their content is (relevant parts):
public ref class WebView sealed : public ContentControl, IRenderWebBrowser
{
public:
virtual void SetCursor(CefCursorHandle cursor);
}
And the implementation:
void WebView::SetCursor(CefCursorHandle cursor)
{
SafeFileHandle^ handle = gcnew SafeFileHandle((IntPtr)cursor, false);
Dispatcher->BeginInvoke(DispatcherPriority::Render,
gcnew Action<SafeFileHandle^>(this, &WebView::SetCursor), handle);
}
CefCursorHandle is defined like this:
#define CefCursorHandle cef_cursor_handle_t
...and cef_cursor_handle_t is defined like this:
#define cef_cursor_handle_t HCURSOR
i.e. a windef.h structure.
The interface (IRenderWebBrowser) btw. defines the method like this.
public interface class IRenderWebBrowser : IWebBrowser
{
public:
void SetCursor(CefCursorHandle cursor);
}
At one point, I thought the problem was related to "const" vs "non-const" issue, but as can be seen in the examples, there is no const specifiers involved. :-(
What is the obvious gotcha I'm missing here? I skimmed through this post but it didn't really help me.
I also thought about the possibility of multiple/old versions of the assemblies hanging around somewhere, so I tried bumping the assembly version just to be sure the right one was loaded - which it was. I've also looked with ILSpy on the assembly and the method is sure there. However, its method signature is this:
public unsafe void SetCursor(HICON__* cursor)
Could it be related to the unsafe part, or the fact that its parameter (HICON__*) is inaccessible from a C#/CLR context? (I'm trying to instantiate the type from a C# assembly.) I must admit that C++/CLI isn't really my area of expertise, yet... :-)
Anyone?
(If someone wants to look into the details more closely, feel free to clone/investigate the project at https://github.com/perlun/CefSharp/ - this stuff lives on the vs2012 branch.)
Followup: I tried to implement the IRenderWebBrowser interface in C#, just to experiment:
public unsafe class Foo : IRenderWebBrowser
{
public void SetBuffer(int width, int height, void* buffer)
{
throw new NotImplementedException();
}
// ...and so forth.
}
Now, compiling this (after enabling the /unsafe flag) gives me a lot more insight into what (might) be causing this:
1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(167,31,167,38): error CS0122: 'HICON__' is inaccessible due to its protection level
1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(167,21,167,30): error CS0051: Inconsistent accessibility: parameter type 'HICON__*' is less accessible than method 'CefSharp.Wpf.Example.Foo.SetCursor(HICON__*)'
1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(182,45,182,52): error CS0122: 'CefRect' is inaccessible due to its protection level
1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(182,21,182,44): error CS0051: Inconsistent accessibility: parameter type 'CefRect*' is less accessible than method 'CefSharp.Wpf.Example.Foo.SetPopupSizeAndPosition(CefRect*)'
If HICON__ is inaccessible to the C#/managed world, it might be quite possible that the fact that these methods exist in the type make the CLR a bit "confused" to say the least, making the type impossible to instantiate from a managed context. Is there any way in C++/CLI to specify that the methods are to be public (to implement the interface in question), but "hidden from CLR" (to avoid stupid TypeLoadExceptions and the like)?
Let's hope this helps someone else... It turned out my suspicion was right, seemingly. Because the types are unmanaged (and inaccessible to the managed world), the C++ compiler creates the CefCursorHandle/HICON struct as an internal CLR struct within the assembly in which the WebView is declared. This makes the method essentially be uncallable (a public method with an internal parameter => impossible to call from C#), and the CLR appears to barf about this when the type is attempted to be instantiated from C#...
Changing the parameter type to IntPtr made the code work as intended. "void *" is also an option, and it can sometimes be easier to use on the C++ side.
(In theses cases, the methods don't need to be used no the C#/managed side so it's not a problem to just using IntPtr/void *. If they were actually being used, proper marshalling would be a better idea than this.)
Bit of a history lesson here. I'm working on a legacy C++/MFC application and am trying to start a incremental modernization by pushing components written in C# (WinForms and later WPF).
I'm stucking using .Net/1.1 and VS/2003 for many reasons which are impossible to resolve in the near future.
Currently, as a proof of concept, something like this works:
#pragma push_macro("new")
#undef new
WinFormA::Form1* myform;
myform = __gc new WinFormA::Form1();
myform->ShowDialog();
#pragma pop_macro("new")
The problem I'm having is this - I need the unmanaged C++/MFC code to pass a callback pointer into the managed C# WinForm code so that I can capture user interactions and have them processed by the application.
I've looked at some articles such as this MSDN article but it doesn't work in VS/2003 (the compiler doesn't like the delegate syntax).
Are there any other options? I don't think I can use DLLImport since I need to interact with the specific application instance not a flat API.
Thanks!
If the other answers don't work out, you could always write a C wrapper to flatten the classes. For example, if the C++ class is:
class TheClass {
public:
TheClass(int Param);
~TheClass();
bool SomeFunction(int Param1,int Param2);
};
I'll write a wrapper:
extern "C" void *TheClass_Create(int Param) {
return (void*) new TheClass(Param);
}
extern "C" void TheClass_Destroy(void *This) {
delete (TheClass*) This;
}
extern "C" bool TheClass_SomeFunction(void *This,int Param1,int Param2) {
return ((TheClass*) This)->SomeFunction(Param1,Param2);
}
Because the wrapper is straight C, you can P/Invoke in C# to your heart's content (the void *This should become an IntPtr to ensure compatibility if you move to 64-bit). Sometimes, if I'm really ambitious, I'll actually write a C# wrapper around the P/Invokes to 're-classify' the thing.
I already forgot .NET 1.*, but:
Define necessary interfaces and register your .NET components as COM objects. .NET utilities will usually provide reasonably good marshaling code.
If possible, access them as COM objects from C++ application without any Managed C++ at all. (Use interface pointers instead of functions for callbacks).
If COM is not an option, use .NET Reflector to see what's going on inside auto-generated interop assemblies - this might give an insight on how to do the same thing manually.
I have never tried it by myself, but did you check RuntimeMethodHandle struct which is definitely exists in .net1?
SomeDelegate Handler = new SomeDelegate(SomeMethod);
IntPtr HandlerPtr = Handler.Method.MethodHandle.GetFunctionPointer();
And some copy-paste from MSDN's description .net2 Marshal::GetDelegateForFunctionPointer Method:
In versions 1.0 and 1.1 of the .NET Framework, it was possible to pass a delegate representing a managed method to unmanaged code as a function pointer, allowing the unmanaged code to call the managed method through the function pointer. It was also possible for the unmanaged code to pass that function pointer back to the managed code, and the pointer was resolved properly to the underlying managed method.