How can I reference a static array defined in another .cpp file

S

silverburgh.meryl

Hi,

In one A.cpp file, I have defined a static array of JSFunctionSpec,
like this:

static JSFunctionSpec JProfFunctions[] = {
{"JProfStartProfiling", JProfStartProfiling,
0, 0, 0
},
{"JProfStopProfiling", JProfStopProfiling,
0, 0, 0},
{nsnull, nsnull,
0, 0, 0}
};


how can I use that JProfFunctions in another .cpp file (say B.cpp)?

i tried this in my B.cpp:

extern JSFunctionSpec[] JProfFunctions[];

void aFunction () {
::JS_DefineFunctions(JProfFunctions);
}

I get compilation error: 'JProfFunctions' was not declared in this
scope
 
D

Dave Rahardja

Hi,

In one A.cpp file, I have defined a static array of JSFunctionSpec,
like this:

static JSFunctionSpec JProfFunctions[] = {
{"JProfStartProfiling", JProfStartProfiling,
0, 0, 0
},
{"JProfStopProfiling", JProfStopProfiling,
0, 0, 0},
{nsnull, nsnull,
0, 0, 0}
};


how can I use that JProfFunctions in another .cpp file (say B.cpp)?

i tried this in my B.cpp:

extern JSFunctionSpec[] JProfFunctions[];

void aFunction () {
::JS_DefineFunctions(JProfFunctions);
}

I get compilation error: 'JProfFunctions' was not declared in this
scope

The fact that you declared the array static means that it is not visible from
another compilation unit.

What are you trying to achieve? Is that array supposed to have internal
(static) linkage?

-dr
 
S

silverburgh.meryl

In one A.cpp file, I have defined a static array of JSFunctionSpec,
like this:
static JSFunctionSpec JProfFunctions[] = {
{"JProfStartProfiling", JProfStartProfiling,
0, 0, 0
},
{"JProfStopProfiling", JProfStopProfiling,
0, 0, 0},
{nsnull, nsnull,
0, 0, 0}
};
how can I use that JProfFunctions in another .cpp file (say B.cpp)?
i tried this in my B.cpp:
extern JSFunctionSpec[] JProfFunctions[];
void aFunction () {
::JS_DefineFunctions(JProfFunctions);
}
I get compilation error: 'JProfFunctions' was not declared in this
scope

The fact that you declared the array static means that it is not visible from
another compilation unit.

What are you trying to achieve? Is that array supposed to have internal
(static) linkage?

-dr


I want to define that array in 1 .cpp file, but other .cpp files can
use the array.
so I should remove the 'static' in my A.cpp file, but how can other
files (e.g. B.cpp) see that array (defined in A.cpp)?


I tried this in my B.cpp:

extern JSFunctionSpec[] JProfFunctions[];

void aFunction () {
::JS_DefineFunctions(JProfFunctions);
}
But I get compilation error: 'JProfFunctions' was not declared in this
scope.
In one A.cpp file, I have defined a static array of JSFunctionSpec,
like this:
static JSFunctionSpec JProfFunctions[] = {
{"JProfStartProfiling", JProfStartProfiling,
0, 0, 0
},
{"JProfStopProfiling", JProfStopProfiling,
0, 0, 0},
{nsnull, nsnull,
0, 0, 0}
};
how can I use that JProfFunctions in another .cpp file (say B.cpp)?
i tried this in my B.cpp:
extern JSFunctionSpec[] JProfFunctions[];
void aFunction () {
::JS_DefineFunctions(JProfFunctions);
}
But I get compilation error: 'JProfFunctions' was not declared in this
scope.
 
J

John Carson

In one A.cpp file, I have defined a static array of JSFunctionSpec,
like this:
static JSFunctionSpec JProfFunctions[] = {
{"JProfStartProfiling", JProfStartProfiling,
0, 0, 0
},
{"JProfStopProfiling", JProfStopProfiling,
0, 0, 0},
{nsnull, nsnull,
0, 0, 0}
};
how can I use that JProfFunctions in another .cpp file (say B.cpp)?
i tried this in my B.cpp:
extern JSFunctionSpec[] JProfFunctions[];
void aFunction () {
::JS_DefineFunctions(JProfFunctions);
}
I get compilation error: 'JProfFunctions' was not declared in this
scope

The fact that you declared the array static means that it is not
visible from another compilation unit.

What are you trying to achieve? Is that array supposed to have
internal (static) linkage?

-dr


I want to define that array in 1 .cpp file, but other .cpp files can
use the array.
so I should remove the 'static' in my A.cpp file


Yes. static in this context means that the definition is restricted to the
translation unit in which it appears. Drop it (and fix the syntax error
pointed out by IV).
 
S

s5n

Hi,

In one A.cpp file, I have defined a static array of JSFunctionSpec,
like this:

static JSFunctionSpec JProfFunctions[] = {
{"JProfStartProfiling", JProfStartProfiling,
0, 0, 0
},
{"JProfStopProfiling", JProfStopProfiling,
0, 0, 0},
{nsnull, nsnull,
0, 0, 0}
};

Try this:

In A.cpp:

JSFunctionSpec * my_funcs()
{
static std::vector<JSFunctionSpec *> funcs;
if( funcs.empty() ){
... populate funcs and end with a trailing null
JSFunctionSpec because JS_DefinFunctions() likes
is that way ...
}
return &funcs[0];
]

Now add that function to your API (A.hpp) so you can reference it from
B.cpp.

[Then, since you're using SpiderMonkey from C++, take a look at my C++
toolkit for SpiderMonkey, which simplifies this type of thing:
http://SpiderApe.sf.net :) :)]

Here's an example taken from the SpiderApe code:

typedef std::vector<JSFunctionSpec *> JSFuncVector;

/**
Used by MonkeyWrapper to get the default array of
script-callable functions.

You may use this vector with JS_DefineFunctions(), but
should follow this guideline:

<pre>
JSFuncVector myvec( standard_js_functions() );
myvec.push_back( 0 );
JS_DefineFunctions(cx,obj, myvec[0]);
</pre>

This ensures that the vector ends with a NULL element, as
required by JS_DefineFunctions(). Since arbitrary code can
add functions to standard_js_functions(), there is normally
no guaranty that the final element is null. It is poor
practice
to add a NULL element to standard_js_functions() because
elements
added after it would be ignored by JS_DefineFunctions().

On the first call to this function, the returned vector is
pre-populated with whatever functions the ape API provides
for script-side code, so this vector will always have at
least a few entries unless client code is foolish enough to
empty it.
*/
APE_PUBLIC_API JSFuncVector & standard_js_functions();



JSBool
init_functions( JSContext * cx, JSObject * obj )
{
/**
2006.05.30: we COPY standard_js_functions() because
older internal code used vector::reserve() and
operator[] to populate the vector. This led to an
incorrect value being returned from vector::size()
and an
uncertainty about whether or not the vector has a
trailing
NULL entry (needed by JS_DefineFunctions()). It is
a wonder
that it ever worked before.
*/
JSFuncVector funcs( standard_js_functions() );
funcs.push_back( 0 ); // ensure a trailing NULL entry
if( ! JS_DefineFunctions( cx, obj, funcs[0] ) )
{
JS_ReportError(cx,"ape::init_functions():
JS_DefineFunctions() failed!");
return JS_FALSE;
}
return JS_TRUE;
}


----- stephan
 
S

silverburgh.meryl

In one A.cpp file, I have defined a static array of JSFunctionSpec,
like this:
static JSFunctionSpec JProfFunctions[] = {
{"JProfStartProfiling", JProfStartProfiling,
0, 0, 0
},
{"JProfStopProfiling", JProfStopProfiling,
0, 0, 0},
{nsnull, nsnull,
0, 0, 0}
};

Try this:

In A.cpp:

JSFunctionSpec * my_funcs()
{
static std::vector<JSFunctionSpec *> funcs;
if( funcs.empty() ){
... populate funcs and end with a trailing null
JSFunctionSpec because JS_DefinFunctions() likes
is that way ...
}
return &funcs[0];
]

Now add that function to your API (A.hpp) so you can reference it from
B.cpp.

[Then, since you're using SpiderMonkey from C++, take a look at my C++
toolkit for SpiderMonkey, which simplifies this type of thing:http://SpiderApe.sf.net :) :)]

Here's an example taken from the SpiderApe code:

typedef std::vector<JSFunctionSpec *> JSFuncVector;

/**
Used by MonkeyWrapper to get the default array of
script-callable functions.

You may use this vector with JS_DefineFunctions(), but
should follow this guideline:

<pre>
JSFuncVector myvec( standard_js_functions() );
myvec.push_back( 0 );
JS_DefineFunctions(cx,obj, myvec[0]);
</pre>

This ensures that the vector ends with a NULL element, as
required by JS_DefineFunctions(). Since arbitrary code can
add functions to standard_js_functions(), there is normally
no guaranty that the final element is null. It is poor
practice
to add a NULL element to standard_js_functions() because
elements
added after it would be ignored by JS_DefineFunctions().

On the first call to this function, the returned vector is
pre-populated with whatever functions the ape API provides
for script-side code, so this vector will always have at
least a few entries unless client code is foolish enough to
empty it.
*/
APE_PUBLIC_API JSFuncVector & standard_js_functions();

JSBool
init_functions( JSContext * cx, JSObject * obj )
{
/**
2006.05.30: we COPY standard_js_functions() because
older internal code used vector::reserve() and
operator[] to populate the vector. This led to an
incorrect value being returned from vector::size()
and an
uncertainty about whether or not the vector has a
trailing
NULL entry (needed by JS_DefineFunctions()). It is
a wonder
that it ever worked before.
*/
JSFuncVector funcs( standard_js_functions() );
funcs.push_back( 0 ); // ensure a trailing NULL entry
if( ! JS_DefineFunctions( cx, obj, funcs[0] ) )
{
JS_ReportError(cx,"ape::init_functions():
JS_DefineFunctions() failed!");
return JS_FALSE;
}
return JS_TRUE;
}

----- stephan
Thanks for all the help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top