I want to enter the following command into the debugger
po [[UIWindow keyWindow] _autolayoutTrace]
How would I do that in Xamarin Studio?
Edit:
I saw this Objective-C code
NSLog(#"%#", [[UIWindow keyWindow] _autolayoutTrace]);
in programatically change autolayout on orientation change together with an interface definition for that.
// for debugging auto layout.
#interface UIWindow (AutoLayoutDebug)
+(UIWindow *)keyWindow;
-(NSString *)_autolayoutTrace;
#end
I'd like to know how this can be done in Xamarin iOS?
If you are using the unified API the solution posted by miguel.de.icaza doesn't work anymore, because you get
`ObjCRuntime.Messaging' is inaccessible due to its protection level
One has to use P/Invoke:
using System;
using System.Runtime.InteropServices;
using Foundation;
using UIKit;
using ObjCRuntime;
public static class UIViewAutolayoutTraceExtensions
{
[DllImport(Constants.ObjectiveCLibrary, EntryPoint="objc_msgSend")]
private static extern IntPtr IntPtr_objc_msgSend (IntPtr receiver, IntPtr selector);
public static NSString AutoLayoutTrace(){
return (NSString)Runtime.GetNSObject(IntPtr_objc_msgSend(UIApplication.SharedApplication.KeyWindow.Handle, new Selector ("_autolayoutTrace").Handle));
}
public static NSString RecursiveDescription(){
return (NSString)Runtime.GetNSObject(IntPtr_objc_msgSend(UIApplication.SharedApplication.KeyWindow.Handle, new Selector ("recursiveDescription").Handle));
}
}
Then you can use it like this:
Console.WriteLine(UIViewAutolayoutTraceExtensions.RecursiveDescription ());
One caveat though: You can only call this code after everything has been loaded. Otherwise KeyWindow will be null. So there is no possibility to set a breakpoint and then call this code. You can only call this code if you provide a button or something similar with which you trigger the action.
using MonoTouch.ObjCRuntime;
var str = new NSString (Messaging.IntPtr_objc_msgSend (UIApplication.SharedApplication.KeyWindow.Handle, new Selector ("_autolayoutTrace").Handle));
And "str" will contain the string that you can then use with Console.WriteLine
Related
I've been trying to convert this WinRT interface from its C++ Origin Code, to C# based code:
IDL File:
namespace Windows.Internal.Security.Authentication.Web{
[version(1)]
[uuid(07650a66-66ea-489d-aa90-0dabc75f3567)]
interface ITokenBrokerInternalStatics : IInspectable {
HRESULT filler_GetTokenSilently();
HRESULT filler_GetSecureInputParameters();
HRESULT filler_ReportBackgroundCompletion();
HRESULT filler_FindAccount();
HRESULT filler_FindAccountForApp();
HRESULT filler_FindAccountForProvider();
HRESULT FindAllAccountsAsync(
[out][retval] Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<Windows.Security.Credentials.WebAccount > *> ** operation);
}
[version(1)]
[static(Windows.Internal.Security.Authentication.Web.ITokenBrokerInternalStatics, 1)]
[marshaling_behavior(agile)]
[threading(both)]
runtimeclass TokenBrokerInternal {
}
}
CPP File:
auto tokenBrokerStatics = get_activation_factory<TokenBrokerInternal, Windows::Foundation::IUnknown>();
auto statics = tokenBrokerStatics.as<ITokenBrokerInternalStatics>();
auto accounts = statics.FindAllAccountsAsync().get();
This is what I got so far:
using PInvoke;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Metadata;
using Windows.Internal.Security.Authentication.Web;
using Windows.Security.Credentials;
using GuidAttribute = System.Runtime.InteropServices.GuidAttribute;
namespace Windows.Internal.Security.Authentication.Web
{
[Version(1)]
[Guid("07650a66-66ea-489d-aa90-0dabc75f3567")]
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface ITokenBrokerInternalStatics
{
Windows.Foundation.IAsyncOperation<IReadOnlyList<Windows.Security.Credentials.WebAccount>> FindAllAccountsAsync();
}
[Version(1)]
[MarshalingBehavior(MarshalingType.Agile)]
[Threading(ThreadingModel.Both)]
[Static(typeof(Windows.Internal.Security.Authentication.Web.ITokenBrokerInternalStatics), 1)]
public class TokenBrokerInternal { }
public static class TokenBrokerInternalAssist
{
public static ITokenBrokerInternalStatics GetTokenBrokerInternal()
{
var tokenBrokerStatics = WindowsRuntimeMarshal.GetActivationFactory(typeof(TokenBrokerInternal));
var statics = (ITokenBrokerInternalStatics)tokenBrokerStatics.ActivateInstance()
return statics;
}
}
}
However, I can't seem to get it to work despite my best efforts. Here's a couple of errors I've encountered while trying to get this working:
Casting Errors
Activation Factories Not Existing
Many Other Errors related to dumb mistakes
I'm pretty new at this WinRT stuff, but despite looking on multiple sites for answers to my problem, I've found myself at a dead-end, and I really just wanna convert this code to C# to avoid having to compile a C++ project twice to support Any CPU and the complicated compiling of my app. What am I doing wrong?
P.S. This is not a UWP app, so don't suggest WebAccountManager or anything UWP specific, please.
is there any function to have the same possibilities like "mono_add_internal_call" in the CLR-Hosting w/o using mono?
Mono
C++ Code:
static MonoString* Sample ()
{
return mono_string_new (mono_domain_get(), "Hello!");
}
mono_add_internal_call ("Hello::Sample", Sample);
C# Code:
using System;
using System.Runtime.CompilerServices;
class Hello {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static string Sample ();
}
Thanks
Instead of "mono_add_internal_call", I use now P/Invoke. It has the same results. So if you call an C# DLL with CLR-Hosting, the P/Invoke calls the CLR-Hosting Dll and not create a new instance.
Thanks to Lucas.
I have a litle program in c#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static int count;
static void Main(string[] args)
{
for (int i = 0; i<10; i++)
{
Console.WriteLine(func_count());
Console.ReadKey();
}
}
static int func_count()
{
return count++;
}
}
}
I want to write another simple C# program that will be able JUST to execute the func_count(). The first exe will be allready running, I don't want to execute it inside the second application and reflect it's properties.
In C after getting the right to access the memory region to avoid seg fault I would have to use a pointer to a function - something like:
int (* func_ptr)(); //pointer to function
func_ptr = func_count_address
What's a simple way to do this in C# like above?
Suppose that the first program (the one given) is as is and I can't change the code.
Thank you
Why not simply call the static method: ConsoleApplication1.Program.func_count(). This of course assumes that you reference the assembly where ConsoleApplication is located within your second app and that the method you want to invoke is public (which is currently is NOT).
EDIT: If you may not change the access-modifier of the desired method you may use reflection to invoke it however.
Sth. like this:
MethodInfo m = typeof(ConsoleApplication.Program).GetMethod("func_count", BindingFlags.NonPublic);
object result = m.Invoke(null, yourParams);
Usually you´d need an instance on which that method is executed. Since your method is static it does not need it and therefor the first param to Invoke is NULL.
I am trying to bind a basic Objective-C library I have created to a Xamarin project. The .h file is:
#import <Foundation/Foundation.h>
#import UIKit;
#interface StarIOFunctions : NSObject {
}
+ (NSMutableData *)GetDataToSendToPrinter:(UIImage *)image;
#end
I have tried to create my binding with the following ApiDefinition:
using System;
using System.Drawing;
using MonoTouch.ObjCRuntime;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace BindingTake2
{
[BaseType (typeof (NSObject))]
interface StarIOFunctions {
[Export ("GetDataToSendToPrinter:image")]
NSMutableData GetDataToSendToPrinter (UIImage image);
}
}
Everything compiles, but when I run it in my application:
UIImage image = UIImage.FromBundle("image1.png");
StarIOFunctions functions = new StarIOFunctions ();
var output = functions.GetDataToSendToPrinter (image);
My application crashes with the following error:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[StarIOFunctions GetDataToSendToPrinter:image]: unrecognized selector sent to instance 0x7cdb50f0
Now, I think it has something to do with me sending an image, and not a pointer to the image - but I'm totally lost and can't work out what exactly I'm doing wrong.
It seems you're including the parameter names in the selector name, i.e.
[Export ("GetDataToSendToPrinter:image")]
should be:
[Export ("GetDataToSendToPrinter:")]
The last column ':' indicates that a parameter is needed - but you do not need to name it (in the selector) as the previous string should imply it.
after along time of searching via google, I decided to poste my problem here.
First: I am total C# Noob. I am using a Macro Recorder from Jitbit and I have no choice to use a different. The Problem is in the Macro Recorder, it is missing some essential things.
Like reading a text file into a variable and paste this variable via Clipboard :-(
However the good thing is, the tool support "some" type of native C# Code
If I open the C# Command I get this:
public class Program
{
public static void Main()
{
System.Windows.Forms.MessageBox.Show("test");
}
}
And the C# program has to follow also these rules:
=> This Code MUST contain a class named "Program" with a static method "Main"
I already used google and found code that should do the job but I get errors, I guess the
code doesn`t follow the above rules.
This is what I found and tried:
using System;
using System.IO;
public class Program
{
public static void Main()
{
// Read the file as one string.
System.IO.StreamReader myFile =
new System.IO.StreamReader("Counter.txt");
string counter = myFile.ReadToEnd();
myFile.Close();
// Load string into clipboard
Clipboard.SetDataObject( counter, true );
}
}
I always get the error : "Line 15: The Name Clipboard is not existing in the context"?!?
I hope that someone can explain a noob (me) what is wrong and what is the correct code.
Thanks.
add reference to System.Windows.Forms
using System;
using System.IO;
using System.Windows.Forms;
public class Program
{
[STAThread]
public static void Main()
{
Clipboard.SetDataObject(File.ReadAllText("Counter.txt"), true);
}
}
Note that to Avoid the ThreadStateException you need to applying the STAThread attribute to your Main() function