07-27-2012 01:04 PM
10-18-2012 09:25 AM
10-19-2012 10:04 AM
Hi
Does the descriptor.xml file in your ANE project has the function names matching the names in the shared object (including case) ?
Also, it is a bit of extra work, but you could try to create a very simple C project (without bps, screen, etc..) that calls the ANE shared object functions directly (with fake and/or null variables). It won't test the ANE functionality here, but the idea is to be sure the ane shared object has no broken dependency, for example.
Cheers
10-22-2012 07:45 AM
12-13-2012 06:24 PM
Was this ever resolved?
I've spent at least 8 hrs trying to get my ANE working again on BB10, and today found the problem:
the native IDE: it doesn't clean. Remove all binaries, then build all.
Probably, I figured that out 6 months ago, when I first built the ANE, but had to rediscover it - arghhh!
12-23-2012 04:04 PM
It could be a Flash Builder 4.6(7) issue, if you use Mac. Discussion and workaround - http://forums.adobe.com/message/4319610
01-15-2013 10:56 PM - edited 01-15-2013 11:40 PM
I think I may have found the issue with the 3500 error. Seems ANEs don't like c++. Changing your code to use pure c worked for me.
****** EDIT ********
I tried using extern "C" { //code } and that did not work, so it looks like you will have to use pure c if you want to build an ANE.
Change that using extern "C" does work. Just make sure all of your code including the initializer/finalizer functions are wrapped in it as well if you have multiple class files.
01-16-2013 08:39 AM
01-16-2013 08:51 AM - edited 01-16-2013 08:58 AM
Here's the code I was using to test it. It's modified from the sample HelloWorld code.
Main.cpp
/* * Copyright (c) 2011 Research In Motion Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "FlashRuntimeExtensions.h" #include <cstdio> #include <cstdlib> #include "BBMInit.h" using namespace std; #ifdef __cplusplus extern "C" { #endif /*================== FUNCTION STUBS/INITIALIZERS ===========================*/ /*================== MANDATORY SYSTEM FUNCTIONS ============================*/ void ExtensionInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet); void ExtensionFinalizer(); void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToSet, const FRENamedFunction** functionsToSet); void ContextFinalizer(FREContext ctx); /*====================== LIBRARY FUNCTIONS ==================================*/ /*=========================== FUNCTION CODE =================================*/ /*=========================== SYSTEM CODE ===================================*/ /** * The runtime calls this method once when it loads an ActionScript extension. * Implement this function to do any initializations that your extension requires. * Then set the output parameters. * * @param extDataToSet * A pointer to a pointer to the extension data of the ActionScript extension. * Create a data structure to hold extension-specific data. For example, allocate * the data from the heap, or provide global data. Set extDataToSet to a pointer * to the allocated data. * @param ctxInitializerToSet * A pointer to the pointer to the FREContextInitializer() function. Set * ctxInitializerToSet to the FREContextInitializer() function you defined. * @param ctxFinalizerToSet * A pointer to the pointer to the FREContextFinalizer() function. Set * ctxFinalizerToSet to the FREContextFinalizer() function you defined. You can * set this pointer to NULL. */ void ExtensionInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet) { *extDataToSet = NULL; *ctxInitializerToSet = &ContextInitializer; *ctxFinalizerToSet = &ContextFinalizer; } /** * The runtime calls this function when it disposes of the ExtensionContext instance * for this extension context. */ void ExtensionFinalizer() { } /** * The runtime calls this method when the ActionScript side calls ExtensionContext.createExtensionContext(). * * @param extData * A pointer to the extension data of the ActionScript extension. * @param ctxType * A string identifying the type of the context. You define this string as * required by your extension. The context type can indicate any agreed-to meaning * between the ActionScript side and native side of the extension. If your extension * has no use for context types, this value can be Null. This value is a UTF-8 * encoded string, terminated with the null character. * @param ctx * An FREContext variable. The runtime creates this value and passes it to FREContextInitializer(). * @param numFunctionsToSet * A pointer to a unint32_t. Set numFunctionsToSet to a unint32_t variable containing * the number of functions in the functionsToSet parameter. * @param functionsToSet * A pointer to an array of FRNamedFunction elements. Each element contains a pointer * to a native function, and the string the ActionScript side uses in the ExtensionContext * instance's call() method. */ void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToSet, const FRENamedFunction** functionsToSet) { char *temp = NULL; int i; // define an array of functions const char *functionNames[] = { "bbm_ane_setUUID", NULL }; FREFunction functionPtrs[] = { bbm_ane_setUUID, NULL }; // count number of functions *numFunctionsToSet = 0; while (functionPtrs[*numFunctionsToSet] != NULL) { (*numFunctionsToSet)++; } FRENamedFunction *functionSet = (FRENamedFunction *)calloc(*numFunctionsToSet, sizeof(FRENamedFunction)); for (i = 0; i < *numFunctionsToSet; i++) { int bufferSize = sizeof(char) * (strlen(functionNames[i]) + 1); temp = (char*) malloc(bufferSize); strncpy(temp, functionNames[i], bufferSize); temp[strlen(functionNames[i])] = '\0'; functionSet[i].name = (uint8_t*) temp; functionSet[i].functionData = NULL; functionSet[i].function = functionPtrs[i]; } *functionsToSet = functionSet; } /** * The runtime calls this function when it disposes of the ExtensionContext instance for this extension context. * * @param ctx * The FREContext variable that represents this extension context. */ void ContextFinalizer(FREContext ctx) { } /*====================== LIBRARY CODE ======================================*/ //============================================================================// /* FREObject Helper functions to use [defined in NativeExtensions.h] //From AS3 to Native FREGetObjectAsInt32 ( FREObject object, int32_t *value ); FREGetObjectAsUInt32( FREObject object, uint32_t *value ); FREGetObjectAsDouble( FREObject object, double *value ); FREGetObjectAsBool ( FREObject object, uint32_t *value ); FREGetObjectAsUTF8 ( FREObject object, uint32_t* length,const uint8_t** value ); int32_t index; FREGetObjectAsInt32( argv[ 0 ], &index ); //From Native to AS3 FRENewObjectFromInt32 FRENewObjectFromUInt32 FRENewObjectFromDouble FRENewObjectFromBool FRENewObjectFromUTF8 (uint32_t length, uint8_t* value, FREObject object); const char *out = "Hello Native\n"; FREObject result; FRENewObjectFromUTF8((uint32_t)(strlen(out) + 1), (uint8_t*) out, &result); */ #ifdef __cplusplus } #endif
My smaple class - BBMInit.cpp & BBMInit.h
/*
* BBMInit.hpp
*
* Created on: Jan 10, 2013
* Author: CHRIS
*/
#ifndef BBMINIT_HPP_
#define BBMINIT_HPP_
#include "FlashRuntimeExtensions.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#ifdef __cplusplus
extern "C" {
#endif
//Set the UUID required for testing the application
FREObject bbm_ane_setUUID(FREContext ctx, void* functionData, uint32_t argc, FREObject argv[]);
#ifdef __cplusplus
}
#endif
/* * BBMInit.cpp * * Created on: Jan 10, 2013 * Author: CHRIS */ #include "FlashRuntimeExtensions.h"
#include "BBMInit.h"
#include <cstdio> #include <cstdlib> #include <cstring> #include <string> using namespace std; #ifdef __cplusplus extern "C" { #endif FREObject bbm_ane_setUUID(FREContext ctx, void* functionData, uint32_t argc, FREObject argv[]) { uint32_t length; const uint8_t * value; char * uuid; FREGetObjectAsUint32( argv[0], &length ); uuid = (char*) malloc(length+1); uuid[length+1] = '\0'; FREGetObjectAsUTF8 ( argv[1], &length, &value ); strncpy(uuid,(char *)value,length); char * temp = "[BBMInit.cpp] - UUID value has been set to \0"; char temp2[200]; strcpy(temp2,temp); strcat(temp2,uuid); char out[200]; strcpy(out,temp2); FREObject result; FRENewObjectFromUTF8((uint32_t)(strlen(out)), (uint8_t *)out, &result); return result; } #ifdef __cplusplus } #endif
My AS3 ANE class - BBMane.as
package {
import flash.external.ExtensionContext;
public class BBMAne {
private var context:ExtensionContext;
private var bbmInit:BBMInit;
public function BBMAne() {
context = ExtensionContext.createExtensionContext( "BSLLC.library.ane.BBM", null );
}
public function setUUID(uuid:String):void {
trace("[BBMInit] settUUID called with value "+uuid);
var out:Object = context.call( "bbm_ane_setUUID", uuid.length, uuid );
trace("Returned from call to bbm_ane_setUUID");
trace(out.toString());
}
}
}
My test application - BBM_ane_test.as
package {
import flash.desktop.NativeApplication;
import flash.desktop.SystemIdleMode;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import qnx.fuse.ui.buttons.LabelButton;
import qnx.fuse.ui.text.Label;
public class BBM_ANE_Test extends Sprite {
var testLbl:Label;
var bbmExtension:BBMAne;
var helloAIR:HelloAIR;
public function BBM_ANE_Test() {
super();
// support autoOrients
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
var testBtn:LabelButton = new LabelButton();
testBtn.label = "Test UUID";
testBtn.width = 300;
testBtn.x = stage.stageWidth / 2 - testBtn.width / 2;
testBtn.y = stage.stageHeight / 2;
testLbl = new Label();
testLbl.width = 600;
testLbl.height = 50;
testLbl.x = stage.stageWidth / 2 - testLbl.width / 2;
testLbl.y = testBtn.y - 75;
testBtn.addEventListener(MouseEvent.CLICK,testUUID );
addChild(testBtn);
addChild(testLbl);
stage.nativeWindow.visible = true;
NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;
}
public function testUUID(e:MouseEvent):void {
bbmExtension = new BBMAne();
bbmExtension.setUUID("1234-5678-90AB-CDEF-GHIJ");
}
}
}
You'll notice in my code that I still use pure c style coding without the use of strings. Even with pure c code, it still fails if run through the c++ compiler because of the function name magnling. I've tried with c++ code styles and it works as long as the ANE functions are not mangled, which is done by using extern "C". Also the function FREGetObjectAsUInt32( FREObject object, uint32_t *value ); is commented out in the NativeExtensions.h file with a warning about causing issues on certain versions of Flash/AIR. It didn't really specify if it was previous or prior to the version it had listed but in the little use that I have made if it I haven't has an issue yet.
Hopefully I will get done with a 1-1 port of the BBMSP functions as an ANE and post it here this weekend. After that I will try to actually make an ANE where most of the background work is done and you just call a function and forget the rest.