[comp.lang.c++] Followup to calling C++ from assembly languag- MASM

emb978@leah.Albany.Edu (Eric M. Boehm) (01/07/90)

This is a somewhat delayed followup to my questions concerning calling
C++ from assembly language.

Below is the sample code from task.hpp:

/* task_control object */
/* routines and methods to interface with and control tasks */
/* this object will initialize and restore interrupt vectors, */
/* keep track of timer ticks, and switch execution between the */
/* task objects */

class task_control{
	private:
		signal ready_q;			// queue of tasks ready to run
		task *current_task;		// current active task
		task_image far *old_stack_ptr;	// return to this stack when done
		unsigned int task_running;	// task switching enabled flag
		unsigned long timer_ticks;	// 18.2 ticks/second
		unsigned int task_lock;		// lock out task switching
	public:
		// task_switch was previously private!
		task_image far *task_switch(task_image far *stk_ptr,
										unsigned int flag,
										signal *sig);
		task_control(void);                // constructor
		void add_new_task(task *new_task); // add new task object to ready q
		void start_tasks(void);	           // start switching tasks on ready_q
		void stop_tasks(void){task_running=0;};
		unsigned long get_timer_ticks(void){return(timer_ticks);};
		void lock(void){task_lock=1;};	    // current task can not be switched
		void unlock(void){task_lock=0;};    // allow task switching
		void send(signal *sig);             // put task from sig q on ready q
		void wait(signal *sig);             // put task on sig q
		void block(void);                   // task allows next to run
};

This is the function name produced by name mangling:

task_switch__12task_controlNP10task_imageUip6signal

glenn@synaptics.com (Glenn Gribble) suggested

> One way to reduce the length of mangled names is to do this:
> 
> #define longClassName LCN
> class longClassName {
> ... blah, blah, blah...
> };

I didn't evey try this because (as you can see from name mangling
above) this wouldn't have gained me anything. Most of the length comes
after the class name.


jb@altair.csustan.edu (John Birchfield) suggested"

> Try using the extern "C" { ... } around your class and its functions.
> The only thing you'll lose is the type-safe linkage -
> 
> You would have to do that for functions called from assembler anyway
> unless you have already gone to the trouble of makeing sure the
> routines calling your C++ know that the C++ functions are using 
> Pascal Calling conventions.  At least it's Pascal to the extent
> that the called procedure cleans up his own stack.  Probably the
> parameters are pushed onto the stack in reverse order also.  I'd
> have to look at the book to be sure.

I wasn't aware that you could use extern "C" with class names. I tried
it but I still got the long mangled name above. I also tried just
declaring the one member function with extern "C" but I received
syntax errors.

bright@dataio.Data-IO.COM (Walter Bright) suggested:

> What version of MASM are you using? Do all MASMs suffer from this? I know
> that MS-LINK doesn't have any problem with it.
> 
> You can solve the problem by writing a "wrapper" function:
> 
> extern "C" task_image far *wrapper(task_control *p, task_image far *t,
> 	unsigned u, signal *s)
> {
> 	return p->task_switch(t,u,s);
> }
> 
> and having your asm routine call it instead.

extern "C"	task_image far *wrapper(
			task_control *p,
			task_image far *stk_ptr,
			unsigned int flag,
			signal *sig);

I tried this and it worked. I am still not clear on why extern "C" didn't
work with the class or with a member function. Reading Lippman didn't
help. Regarding Walter's questions on MASM, I am using MASM 5.1 and I
refer to the MASM 5.0 Programmer's Guide, Sec 4.2, pages 67-69:

... A name can be give any number of characters, but only the first 31
are used. All other characters are ignored.

There were no changes in this area in the 5.1 update manual.

I also tried declaring wrapper as a friend function so I wouldn't have
to make task_switch public, but that didn't work either. I had:

friend ... wrapper (...) {...} in the cheader file;
extern "C" ... wrapper (...) {...} in the source file.

error was:
... previously declared <npfunc....
... now declared <nfunc...

Solutions or suggestions that would allow task_switch to be private
would be appreciated.

-- 
Eric M. Boehm
EMB978@leah.Albany.EDU
EMB978@ALBNYVMS.BITNET