Skip to content

Instantly share code, notes, and snippets.

@brendanzagaeski
Created October 25, 2013 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brendanzagaeski/7160291 to your computer and use it in GitHub Desktop.
Save brendanzagaeski/7160291 to your computer and use it in GitHub Desktop.
Use P/Invoke to call JavaScriptCore's C API functions in iOS.
using System;
using MonoTouch.UIKit;
using MonoTouch;
using System.Runtime.InteropServices;
namespace JintiOS
{
unsafe public partial class JintiOSViewController : UIViewController
{
JSContextRef* context;
unsafe public struct JSStringRef
{
};
unsafe public struct JSValueRef
{
};
unsafe public struct JSContextRef
{
};
unsafe public struct JSClassRef
{
};
unsafe public struct JSObjectRef
{
};
public enum JSPropertyAttributes
{
None = 0,
ReadOnly = 1 << 1,
DontEnum = 1 << 2,
DontDelete = 1 << 3
};
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSGlobalContextCreate")]
public extern static JSContextRef* JSGlobalContextCreate (JSClassRef *globalObjectClass);
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSContextGetGlobalObject")]
public extern static JSObjectRef* JSContextGetGlobalObject (JSContextRef *ctx);
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSStringCreateWithUTF8CString")]
public extern static JSStringRef* JSStringCreateWithUTF8CString (string input);
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSValueMakeNumber")]
public extern static JSValueRef* JSValueMakeNumber (JSContextRef *ctx, double number);
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSEvaluateScript")]
public extern static JSValueRef* JSEvaluateScript (JSContextRef *ctx, JSStringRef *script, JSObjectRef *thisObject, JSStringRef *sourceURL, int startingLineNumber, JSValueRef **exception);
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSValueToNumber")]
public extern static double JSValueToNumber (JSContextRef *ctx, JSValueRef *value, JSValueRef **exception);
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSObjectSetProperty")]
public extern static void JSObjectSetProperty (JSContextRef *ctx, JSObjectRef *obj, JSStringRef *propertyName, JSValueRef *value, JSPropertyAttributes attributes, JSValueRef **exception);
public delegate JSValueRef* JSObjectCallAsFunctionCallback (JSContextRef *ctx, JSObjectRef *function, JSObjectRef *thisObject, UIntPtr argumentCount, JSValueRef** arguments, JSValueRef **exception);
[DllImport (Constants.JavaScriptCoreLibrary, EntryPoint = "JSObjectMakeFunctionWithCallback")]
public extern static JSObjectRef* JSObjectMakeFunctionWithCallback (JSContextRef *ctx, JSStringRef *name, JSObjectCallAsFunctionCallback callAsFunction);
public JintiOSViewController (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
context = JSGlobalContextCreate ((JSClassRef*)IntPtr.Zero);
}
unsafe partial void ButtonClicked (MonoTouch.Foundation.NSObject sender)
{
var button = sender as UIButton;
var cubeAddFunc = new JSObjectCallAsFunctionCallback (
delegate(JSContextRef* ctx, JSObjectRef* function, JSObjectRef* thisObject, UIntPtr argumentCount, JSValueRef** arguments, JSValueRef** exception) {
var x = JSValueToNumber (ctx, arguments [0], (JSValueRef**)IntPtr.Zero);
var y = JSValueToNumber (ctx, arguments [1], (JSValueRef**)IntPtr.Zero);
return JSValueMakeNumber (ctx, x * x * x + y);
});
var jsCubeAddFunc =
JSObjectMakeFunctionWithCallback (context,
JSStringCreateWithUTF8CString ("cubeAndAdd"),
cubeAddFunc);
JSObjectSetProperty (context,
JSContextGetGlobalObject (context),
JSStringCreateWithUTF8CString ("cubeAndAdd"),
(JSValueRef*)jsCubeAddFunc,
JSPropertyAttributes.None,
(JSValueRef**)IntPtr.Zero);
JSStringRef* script = JSStringCreateWithUTF8CString (@"
cubeAndAdd(number, 5)");
JSObjectSetProperty (context,
JSContextGetGlobalObject (context),
JSStringCreateWithUTF8CString ("number"),
JSValueMakeNumber (context, 3),
JSPropertyAttributes.None,
(JSValueRef**)IntPtr.Zero);
var returns = JSValueToNumber (context,
JSEvaluateScript (context, script, (JSObjectRef*)IntPtr.Zero, (JSStringRef*)IntPtr.Zero, 0, (JSValueRef**)IntPtr.Zero),
(JSValueRef**)IntPtr.Zero);
button.SetTitle (returns.ToString (), UIControlState.Normal);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment