ObjectQuery extensions from managed C++/CLI - visual-c++

I'm trying to move a project over to using Entity Framework, but to make it more fun, the project is in C++/CLR.
I've got a query
ObjectQuery<myData::Facility^>^ facQ = myContext->FacilitySet;
and I want to do this
int n = facQ.Count()
But I can't because c++ doesn't recognise extension methods using C# syntax. facQ->Count() doesn't work.
Using C# extension methods from managed C++/CLI shows the answer for user-defined extensions; but in this case, the extension is part of the .NET framework http://msdn.microsoft.com/en-us/library/bb349034%28v=vs.90%29.aspx.
Any ideas?
(I'm using visual studio 2008, and .NET 3.5).

System::Data::Objects::ObjectQuery implements IEnumerable<T>. The Count() method you see in C# is from the System::Linq::Enumerable class.
using namespace System::Linq;
int n = Enumerable::Count(facQ);
Also see this answer, which shows a couple examples of calling other extension methods in that class.

Related

debugging visual C++ properties(hovering over variables does not show value)

I am working on code written in Visual C++17. But a MS specific feature is used namely properties.
Please note that I am not talking about .NET, but the behavior is similar. Most of my collegues including myself have a lot of experience in C# and hence at first glance these properties seem a handy feature.
This is not managed C++, to emphasize and avoid confusion!
The definition in Visual C++ is as follows :
virtual long GetDatumLening() = 0;
virtual void SetDatumLening(long l) = 0;
__declspec(property(get = GetDatumLening, put = SetDatumLening)) long DatumLening;
And using it in the code is like this :
if (hoofdLening->NietHypothecaireLening && hoofdLening->DatumLening < lControleDatum)
Both NietHypothecaireLening and DatumLening are properties defined in the explained manner.
Now my problem is that when I am debugging the application if I hover over those properties the values are not shown whereas properties in C# are shown even if there is some code behind it which is quite nice.
Is there a setting of some kind that I am missing in my Visual Studio environment or is this something I will have to live with ?
The fact that both the getter and setter are virtual should not make a difference, there is of course a non abstract class that implements these methods.
Thanks in advance.

passing object from c# to c++

I've been working on a prototype code application that runs in C# and uses classes and functions from older C++ code (in the form of an imported DLL). The code requirement is to pass in a class object to the unmanaged C++ DLL (from C#) and have it be stored/modified for retrieval later by the C# application. Here's the code I have so far...
Simple C++ DLL Class:
EXPORT_DLL int init(MyInitParams *initparams);
C++ DLL Functions:
struct MyInitParams {
public:
int _np;
int _nm;
int type;
double *CV_Weight;}
in c# DLL
[DllImport("NEWUSEMPC", CallingConvention = CallingConvention.Cdecl, EntryPoint = "init")]
public static extern int init(InitParams parameters);
in c# class
class InitParams
{
public int _np;
public int _nm;
public int type;
public double[] CV_Weight;}
If you own the code of the c++ dll it would be a lot more convenient for you to include it in your solution, and create an interop between c# and c++ using managed c++ as a translation layer. Be aware, that the managed c++ layer should only do the translation of data and invoke the native method, and literally nothing else, because managed c++ is designed only as a bridge between the native and managed world.
You can also use mixed debugger to check out what is happening in both managed and unmanaged code in debug to take a look on the variables, so that you can see what's missing.
I personally would discourage the use of platform invoke instead of an interop class, because the latter is a lot cleaner and is easier to maintain later on.

error calling managed code from unmanaged in C++/CLI

I'm writing a "driver" for a program, the driver communicates with some devices on network. I already have C# software working with the devices, so the plan is to reuse code.
So the driver dll is really an interop between program and and already availible assemblies, it's written in C++/CLI. The program calls methods described in interface, the interop dll calls C# code, that is how I see it.
I implement methods to be called by program using #pragma unmanaged
DeviceSearch::DeviceSearch(IDeviceSearchHandler* handler):m_handler(handler)
{
ManagedWrapper mw;
mw.Init();
}
ManagedWrapper is implemented in managed code, obviously
void ManagedWrapper::Init()
{
//some code
}
However, the problem rises here. If the Init() is empty or calls methods/classes defined in C++, it's working ok. However, if I try to call the C# code (which is referenced using #using , where Facade.dll is the C# dll which performs some functions), I get access violation exception right when mw.Init() is called, not even within it.
Am I missing something really obvious I should do to make the interop work? Most information in the net just tells that it should "just work"
See if this helps:
According to How can i use a C# dll in a Win32 C++ project?
"Define an abstract interface class in your native C++ code, then create a concrete subclass inside the managed C++ DLL. Call into your C# objects in the method implementations.
Finally, export a factory function that will instantiate the implementation class and return a base-class pointer that your native code can use."

Can you force MonoTouch to include an unreferenced assembly in its static compilation?

I have a MonoTouch app that dynamically instantiates a class (using Type.GetType()) at runtime. The class is in an assembly that is not referenced anywhere else in the app, so the MonoTouch static compiler thinks that the assembly isn't used and ignores the assembly when it compiles the app. If I add a reference to the class in the app, then the compiler includes the assembly and the call to Type.GetType() works fine:
MyAssembly a;
I would prefer to just tell the compiler to always include all the assemblies listed in the project's "References" when it compiles the app. Is this possible?
Thanks,
-Tom B.
You will have to change your project's Linker behavior from "Link all assemblies" to "Link SDK assemblies only".
The other solution, if you have the project code that assembly was created with, is to mark the class you want to use with the PreserveAttribute.
Were you able to figure this out yet? If not, I had a similar problem: Is there a way to force MonoDevelop to build/load an assembly?
As I understand it, that's just how the C# compiler works. I was able to get around this by adding a custom pre-build step that scripts a class into the referencing assembly that includes dummy references to the unreferenced assemblies, like so:
using System;
namespace MyNamespace
{
public static class Referencer
{
Type t;
//These lines are scripted one per class in the unreferenced assemblies
//You should only need one per assembly, but I don't think more hurts.
t = typeof(Namespace1.Class1);
t = typeof(Namespace2.Class2);
...
t = typeof(NamespaceN.ClassN);
}
}

How to inherit from DataAnnotations.ValidationAttribute (it appears SecureCritical under Visual Studio debugging host in .NET 4 !)

I have an [AllowPartiallyTrustedCallers] class library containing subtypes of the System.DataAnnotations.ValidationAttribute. The library is used on contract types of WCF services.
In .NET 2/3.5, this worked fine. Since .NET 4.0 however, running a client of the service in the Visual Studio debugger results in the exception "Inheritance security rules violated by type: '(my subtype of ValidationAttribute)'. Derived types must either match the security accessibility of the base type or be less accessible." (System.TypeLoadException)
The error appears to occure only when all of the following conditions are met:
a subclass of ValidationAttribute is in an AllowPartiallyTrustedCallers assembly
reflection is used to check for the attribute
the Visual Studio hosting process is enabled (checkbox on Project properties, Debug tab)
So basically, in Visual Studio.NET 2010:
create a new Console project,
add a reference to "System.ComponentModel.DataAnnotations" 4.0.0.0,
write the following code:
.
using System;
[assembly: System.Security.AllowPartiallyTrustedCallers()]
namespace TestingVaidationAttributeSecurity
{
public class MyValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute
{ }
[MyValidation]
public class FooBar
{ }
class Program
{
static void Main(string[] args)
{
Console.WriteLine("ValidationAttribute IsCritical: {0}",
typeof(System.ComponentModel.DataAnnotations.ValidationAttribute).IsSecurityCritical);
FooBar fb = new FooBar();
fb.GetType().GetCustomAttributes(true);
Console.WriteLine("Press enter to end.");
Console.ReadLine();
}
}
}
Press F5 and you get the exception !
Press Ctrl-F5 (start without debugging), and it all works fine without exception...
The strange thing is that the ValidationAttribute will or will not be securitycritical depending on the way you run the program (F5 or Ctrl+F5). As illustrated by the Console.WriteLine in the above code. But then again, this appear to happen with other attributes (and types?) too.
Now the questions...
Why do I have this behaviour when inheriting from ValidationAttribute, but not when inheriting from System.Attribute ? (Using Reflector I don't find special settings on the ValidationAttribute class or it's assembly)
And what can I do to solve this ? How can I keep MyValidationAttribute inheriting from ValidationAttribute in an AllowPartiallyTrustedCallers assembly without marking it SecurityCritical, still using the new .NET 4 level 2 security model and still have it work using the VS.NET debug host (or other hosts) ??
Thanks a lot!
Rudi
Why do I have this behaviour when inheriting from ValidationAttribute, but not when inheriting from System.Attribute ? (Using Reflector I don't find special settings on the ValidationAttribute class or it's assembly)
This is because the System.ComponentModel.DataAnnotations assembly is conditionally APTCA i.e. it is marked with the following attribute.
[assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel = PartialTrustVisibilityLevel.NotVisibleByDefault)]
Something about the way Visual Studio starts the host process causes the CLR not to respect APTCA on this assembly even though the default AppDomain is fully trusted. This implies that all the types and methods in the DataAnnotations assembly are SecurityCritical. Since a security transparent type (MyValidationAttribute) cannot inherit from a security critical type (ValidationAttribute), this exception is thrown.
And what can I do to solve this ? How can I keep MyValidationAttribute inheriting from ValidationAttribute in an AllowPartiallyTrustedCallers assembly without marking it SecurityCritical, still using the new .NET 4 level 2 security model and still have it work using the VS.NET debug host (or other hosts) ??
It seems like this is a bug with the VS host, which is unfortunate for your situation. On the other hand, you should really be sure that you want your assembly to be APTCA. If it's necessary, then you have a couple of options.
You can leave your assembly as is. This is advantageous because in the most typical partial trust environment, ASP.NET, the DataAnnotations assembly will always be considered APTCA. Of course, you lose the ability to use the debugger in the VS hosting process.
You can mark your assembly C-APTCA as well. You'll be able to use the debugger in the VS hosting process, but consumers of your assembly in ASP.NET will need to add your assembly to the <partialTrustVisibleAssemblies> element in the web.config in order for it to be APTCA.
You could make your attribute SecurityCritical, so you'll be able to use the debugger and will not require any special configuration in ASP.NET, but all classes that use your attribute must also be critical.
For some reason the site posted the text into a completely different question from the one that was on the page when I was writing - weird.

Resources