Hello, I am porting windows console app onto mac.
As I understood there are several options available:
1) Native Xamarin.Mac applicaiton (native and jitted)
2) Regular Console Application ( plain .net 4.5)
So I stick with the #2 approach. Everything works great, except I can't reference native API's.
I need code in this namespaces:
using MonoMac.Foundation; using MonoMac.Security;
I tried referencing monomac.dll from packages tab, it did not provide any namespaces, code was not able to compile.
I tried referencing xammac.dll, xamarin studio stopped whining about missing namespace, but at runtime, thing blows up immediately when I try to construct SecRecord
searchRecord = new SecRecord(SecKind.Key) { Service = ServiceName, Account = path };
with super useful exception ArgumentCantBeNull argument name "obj", probably meaning it was not able to successfully finish native call.
Any help?
Answers
Ok, after some lucky guess
I end up with following approach
Call
To be able to call it, I had to include "xammac.dylib" as a copy to output folder dependency.
Even though it worked, it looks like a hack, which will shoot me after another update to xamarin.
Any tips on how to properly setup .net 4.5 console app to call native mac apis?
So, that'd work in the sense of "it currently appears to work, but we are not supporting doing this that way. I don't see how it'd break in the future but it might and you get to keep the pieces"
So I see a few ways forward for you:
Something like https://github.com/abock/EmbeddedXamarinMac where you embed the mono runtime into a native application and spin it up.
Make an actual XM application and do some magic to make it nice to call from the command line. You can hide the doc icon (http://stackoverflow.com/questions/620841/how-to-hide-the-dock-icon), only call NSApplication.Init () and create a nice symlink to make it easily callable from the command line:
- Pros - You get to leverage our launcher / bootstrap code and know it should "just work".
- Cons - if you need to pass arguments from the command line to your process, that can be super challenging.
Do what you are doing now until it breaks.
- Pros - It works, it is already done.
- Cons - Not supported use case, could break in the future.
Random 4th option - Have you tried dlopen'ing the native library in question (/System/Library/Frameworks/Security.framework/Security) before you use the API. If You are really just invoking that one API, you might be able to get away with doing that and never calling NSApplication.Init ().