0

I have a function type, from SpiderMonkey:

typedef bool (* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp);

I need to construct an array of structures containing references to methods of this type.

I need to make these using function templates with parameters as references to methods of some classes.

I've managed to pass class data members pointers to these templates:

template<typename PrivateType> class jsObjectDataClass : public jsBaseDataClass<PrivateType>
{
public:

template <typename pT, typename jspT, pT PrivateType::*Property> static bool GetProperty(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
PrivateType* data = ...; // initialize here an object having the Property data member
...
data->*Property; // use here the Property data member of an object called 'data'
...
}

and use it as:

const JSPropertySpec jsAIDocumentMiPrintRecord::fProperties[] = {
JS_PSGS("paperRect", (jsAIDocumentMiPrintRecord::GetProperty<AIRect, jsAIRect, &AIDocumentMiPrintRecord::paperRect>), (jsAIDocumentMiPrintRecord::SetProperty<AIRect, jsAIRect, &AIDocumentMiPrintRecord::paperRect>), JSPROP_PERMANENT | JSPROP_ENUMERATE),
...
JS_PS_END
};

It works to pass and get set object's data members.

To resume, the following:

template <typename pT, typename jspT, pT PrivateType::*Property> static bool GetProperty(JSContext *cx, unsigned argc, JS::Value *vp)

becomes:

jsAIDocumentMiPrintRecord::GetProperty<AIRect, jsAIRect, &AIDocumentMiPrintRecord::paperRect>(JSContext *cx, unsigned argc, JS::Value *vp)

is matched with:

typedef bool (* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp);

I need a similar thing for a limited type of methods instead of data members(well, "limited" is not "a few"), meaning some method like:

template <typename jsType, typename PrivateType, AIErr (SuiteType::*SuiteGetMethod)(PrivateType&)> static bool GetMethod(JSContext *cx, unsigned argc, JS::Value *vp)
    {
...

SuiteType* fSuite = ...; init the object that contains the method to be called

AIErr aiErr = kNoErr;

            PrivateType pt;

            if (fSuite)
                aiErr = fSuite->*SuiteGetMethod(pt); // call here the method of specific type
...
}

... but it seems that this is not matched as:

typedef bool (* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp);

to be used as:

const JSFunctionSpec jsAIDocumentSuite::fFunctions[] = {
JS_FN("GetDocumentFileSpecification", (jsAIDocumentSuite::GetMethod<jsAIFilePath, ai::FilePath, &AIDocumentSuite::GetDocumentFileSpecification>), 1, 0),
...
    JS_FS_END
};

where we have:

struct AIDocumentSuite {

    /** Retrieves the file specification for the current document.
            @param file [out] A buffer in which to return the file specification.
        */
    AIAPI AIErr (*GetDocumentFileSpecification) ( ai::FilePath &file );
...
};

What is the solution?

Thanks.

mike
  • 408
  • 5
  • 18
  • The error is: `Error C2440 'initializing' : cannot convert from 'overloaded-function' to 'JSNative'` – mike Jan 18 '16 at 18:46
  • Try passing that member functions by reference, and get it's reference from std::mem_fun_ref ( eg. `std::mem_fun_ref(&myClass::myMethod)` ) – Marqin Jan 18 '16 at 18:49
  • Also, see [this](http://stackoverflow.com/questions/17852738/c-pointers-to-overloaded-functions). – Marqin Jan 18 '16 at 18:53
  • I don't know what to say, it is about data members of a structure, which are pointers to functions. I can't make it work or I misunderstand the article... – mike Jan 18 '16 at 19:25
  • 1
    You need to get rid of the noise in the above question. Reduce it down to a sscce -- or mcve. See this https://stackoverflow.com/help/mcve -- read it and give it a try. The goal is to remove *EVERYTHING* that doesn't lead directly to your compile error. And produce a short bit of code that generates it. Even down to `"GetDocumentFileSpecification"` is whose value *clearly* doesn't cause the error. Delete all the garbage. No `...`, just code that compiles and generates your error. But is minimal. And yes, this is work. – Yakk - Adam Nevraumont Jan 18 '16 at 19:58
  • Right. I have found a solution regarding the function signature: `template static bool GetMethod(JSContext *cx, unsigned argc, JS::Value *vp)`. Now, I need to find the way to call that method. – mike Jan 18 '16 at 20:53

1 Answers1

0

So, the solution is...

... the template function and the call to the method are:

template <typename jsType, typename PrivateType, AIErr(*SuiteType::*SuiteGetMethod)(PrivateType&)> static bool GetMethod(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
SuiteType* fSuite = ...; init the object that contains the method to be called

AIErr aiErr = kNoErr;

PrivateType pt;

if (fSuite)
    aiErr = (fSuite->*SuiteGetMethod)(pt); // call here the method of specific type
...
}
mike
  • 408
  • 5
  • 18