I am buiding a simple XPCOM component. but firefox crashes everytime when I am trying to call a method of this xpcom component.
the file hierarchy is below:
HelloXpcom.xpi
---chrome.manifest
---install.rdf
---chrome
------content
---------sample.xul
---components
------HelloXpcom.dll
------nsISample.xpt
chrome.manifest snippet
content sample chrome/content/
interfaces components/nsISample.xpt
binary-component components/HelloXpcom.dll
overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
my interface idl:
#include "nsISupports.idl"
[scriptable, uuid(F7F48977-382E-461B-B04A-44567EE6D45A)]
interface nsISample : nsISupports
{
attribute string value;
void writeValue(in string aPrefix);
void poke(in string aValue);
};
use xpidl.exe to generate npISample.h and npISample.xpt.
and all the implementation methods are almost nothing, just do some simple thing.
sample.xul
<?xml version="1.0"?>
<overlay id="sample"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<statusbar id="status-bar">
<script>
function DoXPCOM()
{
try {
alert("1");
var sample = Components.classes["#baofeng/sample;1"].createInstance();
alert("2");
sample = sample.QueryInterface(Components.interfaces.nsISample);
alert("3");
dump("sample = " + sample + "\n");
}
catch(err) {
alert(err);
return;
}
var res = sample.SetValue("123");
var str = "";
obj.GetValue(str);
alert(str);
}
</script>
<button label="xpcom" oncommand="DoXPCOM();"/>
</statusbar>
</overlay>
"alert("1");" is executed, It crashes at "Components.classes["#baofeng/sample;1"].createInstance();" the contact ID "#baofeng/sample;1" is recognized by firefox, if not, there should be some info like "#baofeng/sample;1" undefined pops out. So the createInstance() method is the point.
can someone help me out of this?
Related
I need to have a callback function to listen for some events in native module and transfers data from native to javascript and I want to call this javascript function from native directly in React Native iOS app without sending events to NativeEventEmitter.
How to implement this with JSI (JavaScript Interface)?
First, your function must be defined globally in javascript e.g.:
App.js
global.greeting = function(param) {
return "Hello " + param + "!";
};
Then you should find and call it with React Native Runtime in native:
AppDelegate.mm
#include <jsi/jsi.h>
#import <React/RCTBridge+Private.h>
using namespace facebook::jsi;
using namespace std;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
// Runtime notification
[NSNotificationCenter.defaultCenter addObserverForName:RCTJavaScriptDidLoadNotification object:nil queue:nil
usingBlock:^(NSNotification* notification) {
// Get runtime
RCTCxxBridge* cxxbridge = (RCTCxxBridge*)notification.userInfo[#"bridge"];
if (cxxbridge.runtime) {
Runtime& runtime = *(Runtime*)cxxbridge.runtime;
// Get global function
Function greeting = runtime.global().getPropertyAsFunction(runtime, "greeting");
// Call with param
Value param = Value(runtime, String::createFromUtf8(runtime, "JSI"));
Value result = greeting.call(runtime, move(param), 1);
string str = result.asString(runtime).utf8(runtime);
printf("Result: %s", str.c_str());
}
}];
return YES;
}
Outputs:
Result: Hello JSI!
Note: Since the sample uses JSI for synchronous native methods access, remote debugging (e.g. with Chrome) is no longer possible. Instead, you should use Flipper for debugging your JS code.
I am looking for a way in the Dart programming language to redirect the
output from stdout, into a "Something", that I can call .toString() on, and get
anything printed on stdout as String. This is useful for unit tests.
Currently I wrap stdout in my Display class, and store the text for one call and verify that stdout's write is
used. See also my side note below, how it can be done in Java.
import 'dart:io';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
class Display {
IOSink output;
String lastTextPrinted;
Display(IOSink output) {
this.output = output;
}
void myPrint(String text) {
lastTextPrinted = text;
output.write(text);
}
}
main() {
test('prints hello world', () {
Display display = new Display(stdout);
display.myPrint("Hello world!");
expect("Hello world!", display.lastTextPrinted);
});
test('myPrint calls ioSinks write', () {
MockIOSink ioSink = new MockIOSink();
Display display = Display(ioSink);
display.myPrint("Hello world!");
verify(ioSink.write("Hello world!"));
});
}
class MockIOSink extends Mock implements IOSink {}
Sidenote: In Java with JUnit 4 I used something similar to this:
There System.out is a PrintStream and I can assign my own Stream to it, for instance ByteArrayOutPutStream.
The latter has a .toString method I can call to verify its content against.
#Test
public void testMyMessageToDisplay() throws Exception
{
ByteArrayOutputStream canvas = new ByteArrayOutputStream();
System.setOut(new PrintStream(canvas);
new Display().displayMyMessage("Hello world!");
Assert.assertEquals("Hello World!", canvas.toString("UTF-8"));
}
public static class Display {
public void displayMyMessage(String myMessage) {
System.out.println(myMessage);
}
}
Look at https://pub.dartlang.org/packages/test_process – it gives a lot of nice methods for verifying the output of a process
See the example in the readme:
import 'package:test/test.dart';
import 'package:test_process/test_process.dart';
void main() {
test("pub get gets dependencies", () async {
var process = await TestProcess.start("pub", ["get"]);
// Each stream matcher will consume as many lines as it matches from a
// StreamQueue, and no more, so it's safe to use them in sequence.
await expectLater(process.stdout, emits("Resolving dependencies..."));
// The emitsThrough matcher matches and consumes any number of lines, as
// long as they end with one matching the argument.
await expectLater(process.stdout, emitsThrough("Got dependencies!"));
await process.shouldExit(0);
});
}
I am trying to use a library for showing Flash Messages https://github.com/elpete/flashmessage But I am having trouble getting it working correctly. The documentation isn't that great and I am new to ColdFusion. I want to have the ability to have persistent error messages across pages. Specifically during checkout so when the user needs to go back or a validation error occurs the message will appear. According to the documentation:
The FlashMessage.cfc needs three parameters to work:
A reference to your flash storage object. This object will need
get(key) and put(key, value) methods. A config object with the
following properties: A unique flashKey name to avoid naming
conflicts. A reference to your containerTemplatePath. This is the view
that surrounds each of the individual messages. It will have
references to a flashMessages array and your messageTemplatePath. A
reference to your messageTemplatePath. This is the view that
represents a single message in FlashMessage. It will have a reference
to a single flash message. The name is chosen by you in your container
template. Create your object with your two parameters and then use it
as normal.
I am getting the error
the function getMessages has an invalid return value , can't cast null value to value of type [array]
I had this script somewhat working at one point but it seems very finicky. I believe it is my implementation of it. I am hoping someone here can help me figure out where I went wrong. Or give me some pointers because I am not sure I am even implementing it correctly.
This is What I have in my testing script:
<cfscript>
alertStorage = createObject("component", 'alert');
config = {
flashKey = "myCustomFlashKey",
containerTemplatePath = "/flashmessage/views/_templates/FlashMessageContainer.cfm",
messageTemplatePath = "/flashmessage/views/_templates/FlashMessage.cfm"
};
flash = new flashmessage.models.FlashMessage(alertStorage, config);
flash.message('blah');
flash.danger('boom');
</cfscript>
And inside of alert.cfc I have:
component {
public any function get(key) {
for(var i = 1; i < ArrayLen(session[key]); i++) {
return session[key][i];
}
}
public any function put(key, value) {
ArrayAppend(session.myCustomFlashKey, value);
return true;
}
public any function exists() {
if(structKeyExists(session,"myCustomFlashKey")) {
return true;
} else {
session.myCustomFlashKey = ArrayNew();
return false;
}
}
}
The Flash Message Component looks like this:
component name="FlashMessage" singleton {
/**
* #flashStorage.inject coldbox:flash
* #config.inject coldbox:setting:flashmessage
*/
public FlashMessage function init(any flashStorage, any config) {
instance.flashKey = arguments.config.flashKey;
singleton.flashStorage = arguments.flashStorage;
instance.containerTemplatePath = arguments.config.containerTemplatePath;
instance.messageTemplatePath = arguments.config.messageTemplatePath;
// Initialize our flash messages to an empty array if it hasn't ever been created
if (! singleton.flashStorage.exists(instance.flashKey)) {
setMessages([]);
}
return this;
}
public void function message(required string text, string type = "default") {
appendMessage({ message: arguments.text, type = arguments.type });
}
public any function onMissingMethod(required string methodName, required struct methodArgs) {
message(methodArgs[1], methodName);
}
public any function render() {
var flashMessages = getMessages();
var flashMessageTemplatePath = instance.messageTemplatePath;
savecontent variable="messagesHTML" {
include "#instance.containerTemplatePath#";
}
setMessages([]);
return messagesHTML;
}
public array function getMessages() {
return singleton.flashStorage.get(instance.flashKey, []);
}
private void function setMessages(required array messages) {
singleton.flashStorage.put(
name = instance.flashKey,
value = arguments.messages
);
}
private void function appendMessage(required struct message) {
var currentMessages = getMessages();
ArrayAppend(currentMessages, arguments.message);
setMessages(currentMessages);
}
}
I'm struggling with Adobe Air native process communication. I'd like to pass an c++ exe shellcommands stored at processArgs when started. The c++ program uses this arguments to choose device channel and symbolrate of an CAN-Bus-Adapter. The c program itself creates an json database for an html page. While the c program is processing i'd like to get some feedback of the program and if it exits adobe air should create a link for the html page with the function onExit. The c program uses standart output of iostream lib ("cout", "cerr") to send messages to adobe air.
Adobe Air script:
var process;
function launchProcess()
{
if(air.NativeProcess.isSupported)
{
setupAndLaunch();
}
else
{
air.Introspector.Console.log("NativeProcess not supported.");
}
}
function setupAndLaunch()
{
var cpp_device = $( "#device option:selected" ).val();
var cpp_channel= $("#channel option:selected").text();
var cpp_symbolRate= $("#symbolRate option:selected").val();
air.Introspector.Console.log("CHANNEL",cpp_channel);
air.Introspector.Console.log("Device",cpp_device);
air.Introspector.Console.log("Symbol Rate",cpp_symbolRate);
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
var file = air.File.applicationDirectory.resolvePath("InteractiveDocumentation.exe");
nativeProcessStartupInfo.executable = file;
var processArgs = new air.Vector["<String>"]();
processArgs.push(cpp_device);
processArgs.push(cpp_channel);
processArgs.push(cpp_symbolRate);
nativeProcessStartupInfo.arguments = processArgs;
process = new air.NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
process.addEventListener(air.ProgressEvent.STANDARD_ERROR_DATA, onErrorData);
process.addEventListener(air.IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
process.addEventListener(air.IOErrorEvent.STANDARD_ERROR_IO_ERROR, onIOError);
process.addEventListener(air.NativeProcessExitEvent.EXIT, onExit);
}
function onOutputData(event)
{
air.Introspector.Console.log("Got: ", process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable));
}
function onErrorData(event)
{
air.Introspector.Console.log("ERROR -", process.standardError.readUTFBytes(process.standardError.bytesAvailable));
}
function onExit(event)
{
air.Introspector.Console.log("Process exited with ",event.exitCode);
$("#output").html("Start");
}
function onIOError(event)
{
air.Introspector.Console.log(event.toString());
}
$(function()
{
$("#start").click(function()
{
air.Introspector.Console.log("START");
launchProcess();
});
});
the c program is quite long, and here i post only the main part
int main( int argc, char *argv[])
{
//! get shell commands for init
// echo shell commands
for( int count = 0; count < argc; count++ )
{
cout << " argv[" << count << "] "
<< argv[count];
}
// handle data
intDevice = (int)(argv[1][0] - '0');
intChannel = (int)(argv[2][0] - '0');
intChannel -= 1;
intSymbolRate = atoi(argv[3]);
//! class function calls
useDll CanFunction;
try
{
CanFunction.initProg();
CanFunction.ecuScan();
CanFunction.openSession();
CanFunction.readECU();
CanFunction.stopProg();
return 0;
}
//! exception handling
catch(int faultNumber)
{
....
}
}
First I used only the onExit listener and everything works fine. After I used start conditions adobe air only responses if i call no class functions except the CanFunction.initProg() and the onExit function was called but skipped the jQuery command to create the link. If I add the class function calls, the c program is called and the json database created but Adobe Air doesnt received any responses. The json database is still created. This confuses me.
My c program uses some *.dll files to communicate with the bus so i could imagine that it is a windows problem. But it is still weird.
Has anybody an idea why adobe air communication doesnt work with my c program if i call my class functions or why the jQuery command is skipped?
Or is there a better solution to call a c++ exe from adobe air?
How do I create a webservice using Mono For Android? It seems like everything is about consuming a webservice, and not really about creating one.
I've tried using this: http://www.mono-project.com/Writing_a_WebService
But System.Web.Services.WebService doesn't exist. System.ServiceModel hasn't been translated yet either. Does anyone have clues on how to create a webservice on Mono For Android?
Thanks
I have now tried to implement the following code and tried to run it in the emulator, but the request I make either through my browser or through a REST client, never reaches the HandleRequest.
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var startBtn = FindViewById<Button>(Resource.Id.StartBtn);
stopBtn.Clickable = false;
startBtn.Click += SetupListener;
}
private void SetupListener(object sender, EventArgs e) {
_httpListener = new HttpListener();
_httpListener.Prefixes.Add("http://*:9876/");
_httpListener.Start();
_httpListener.BeginGetContext(HandleRequest, _httpListener);
}
private void HandleRequest(IAsyncResult result) {
var context = _httpListener.EndGetContext(result);
var response = "<html>Hello World</html>";
var buffer = Encoding.UTF8.GetBytes(response);
context.Response.ContentLength64 = buffer.Length;
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
_httpListener.BeginGetContext(HandleRequest, _httpListener);
}
I have tried making request like the following: http:// localhost:9876/ , http:// 10.1.1.190:9876/ and http:// 10.0.2.2:9876/ but none of them actually reaches into the application.