AIR Native Extensions "The extension context does not have a method with the name"

Chris Smith picture Chris Smith · Dec 2, 2011 · Viewed 8.1k times · Source

I am attempting to make an AIR Native Extension and after successful compilation of all components, Flash Builder 4.6 logs "Error #3500: The extension context does not have a method with the name...".

Here's the C++ code for the native DLL:

#include "stdafx.h"
#include "TestANE.h"

#include "FlashRuntimeExtensions.h"

#include <string>
#include <iostream>
#include <iomanip>
#include <algorithm>

using namespace std;

FREObject isSupported(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
    FREObject result;

    uint32_t isSupportedSwitch = 1;
    FRENewObjectFromBool(isSupportedSwitch, &result);

    return result;
}

FREObject getString(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
    FREObject result;

    const char *testString = "Hello World from C++!";
    FRENewObjectFromUTF8(strlen(testString)+1, (const uint8_t *) testString, &result);

    return result;
}

void taneContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctions, const FRENamedFunction** functions) { 
    *numFunctions = 2;
    FRENamedFunction* func = (FRENamedFunction*) malloc(sizeof(FRENamedFunction) * (*numFunctions));

    func[0].name = (const uint8_t*) "isSupported";
    func[0].functionData = NULL;
    func[0].function = &isSupported;

    func[1].name = (const uint8_t*) "getString";
    func[1].functionData = NULL;
    func[1].function = &getString;

    *functions = func;
}

void taneContextFinalizer(FREContext ctx) {
    return;
}

void taneInitializer(void** extData, FREContextInitializer* ctxInitializer, FREContextFinalizer* ctxFinalizer) { 
    *ctxInitializer = &taneContextInitializer;
    *ctxFinalizer = &taneContextFinalizer;
}

void taneFinalizer(void* extData) {
    return;
}

Here's the code for the ActionScript 3 interface:

package com.tests.TestANE {
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;
    import flash.external.ExtensionContext;

    public class TestANE extends EventDispatcher {

        private var _ExtensionContext:ExtensionContext;

        public function TestANE(target:IEventDispatcher=null) {

            this._ExtensionContext = ExtensionContext.createExtensionContext("com.tests.TestANE", null);

            super(target);
        }

        public function isSupported():Boolean {
            return _ExtensionContext.call("isSupported") as Boolean;
        }

        public function getString():String {
            return _ExtensionContext.call("getString") as String;
        }

        public function dispose():void {
            this._ExtensionContext.dispose();
        }
    }
}

Any help in solving this issue would be appreciated.

Answer

Andrea picture Andrea · Sep 6, 2012

Please see before here: http://forums.adobe.com/thread/923158

If you got this error when you have more than one extension inside the same project, please be careful: EVERY initializer end finalizer methods MUST have different and unique names between ALL the extensions. NB. Not only the methods specified in extension.xml but also the ones you delagate to initialize the context. To be clear: NOT only the extension initializer but also the context initializer inside the project MUST have unique names between ALL the extensions.

Eg.:

 void UNIQUE_NAME_ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, 
                    FREContextFinalizer* ctxFinalizerToSet) {

       NSLog(@"Entering ExtInitializer()");

       *extDataToSet = NULL;
       *ctxInitializerToSet = &UNIQUE_NAME_ContextInitializer;
       *ctxFinalizerToSet = &UNIQUE_NAME_ContextFinalizer;

       NSLog(@"Exiting ExtInitializer()");
}

void UNIQUE_NAME_ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, 
                        uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet) 
{

    *numFunctionsToTest = 1;

    FRENamedFunction* func = (FRENamedFunction*) malloc(sizeof(FRENamedFunction) * 1);
    func[0].name = (const uint8_t*) "scan";
    func[0].functionData = NULL;
    func[0].function = &scan;

    *functionsToSet = func;
}

And the same for the finalizer.

I hope this helps.