Silverfrost Forums

Welcome to our forums

C_EXTERNAL slink bug

2 Oct 2006 8:11 #1107

The slink.exe crashes

00410530 chainSectionNameExact(<ptr>char,longÄunsignedÄint) [+0165] 00410744 chainSectionName(<ptr>char,longÄunsignedÄint) [+0198] 00410fd5 chainSections(void) [+002f] 0040766a parcelUpExe(void) [+08b0] 0040c049 parseCommandLine(<ptr><ptr>char) [+03ab] 0040caf4 main [+00c3]

when compiling (this program creates a shared memory and reads and writes to it) C++ header...

extern 'C' 
{
	void *createShM(char *name, unsigned int &size);
	void destroyShM(void * shm);
	void initShM(void *shm, unsigned int start, unsigned int finish);
	void setShMHour(void *shm, unsigned int hour);
	unsigned int getShMState(void *shm);
	void setShMState(void *shm, unsigned int state);
};

FTN95 code

PROGRAM TEST_SHARED_MEMORY
! void *createShM(char *name, unsigned int &size);
	C_EXTERNAL createShM 'createShM' (ref,ref) : INTEGER

! void destroyShM(void * shm);
	C_EXTERNAL destroyShM 'destroyShM' (ref)

! void initShM(void *shm, unsigned int start, unsigned int finish);
	C_EXTERNAL initShM 'initShM' (ref,val,val)

! void setShMHour(void *shm, unsigned int hour);
	C_EXTERNAL setShMHour 'setShMHour' (ref,val)

! unsigned int getShMState(void *shm);
	C_EXTERNAL getShMState 'getShMState' (ref) : INTEGER

! void setShMState(void *shm, unsigned int state);
	C_EXTERNAL setShMState 'setShMState' (ref,val)

  INTEGER state,size,istate
  INTEGER hour,start,finish
  INTEGER handle
  CHARACTER c
  CHARACTER(LEN=64) name
  
  istate=0
  WRITE(*,*) 'Name: '
  READ(*,*) name
  size=0
  handle = createShM(name,size)
  WRITE(*,*) 'Create returned ', handle
  WRITE(*,*) 'Enter start finish :'
  READ(*,*) start,finish
  CALL initShM(handle,start,finish)
  state=1
  CALL setShMState(handle,state)
  WRITE(*,*) 'Enter (''X'' (state =0) | ''Q'' (quit) | ''Z'' (state=1)) number:'
  DO
   istate = getShMState(handle)
   write(*,*) 'state: ', istate
   
   READ(*,*) c
   IF(c == 'Q' .OR. c == 'q') THEN
     EXIT
   ELSE
     IF(c == 'X' .OR. c == 'x') THEN
       state = 1
       CALL setShMState(handle,state)
     ELSEIF(c=='Z' .OR. c == 'z') THEN
       state =0
       CALL setShMState(handle,state)
     ENDIF
     READ(*,*) hour
     CALL setShMHour(handle,hour)
   ENDIF
  END DO
  WRITE(*,*) 'Destroying ShM'
  CALL destroyShM(handle)
END PROGRAM
3 Oct 2006 3:41 #1111

I had forgotten to say that I'm linking to a static lib (used in other C++ modules) that contains the following: (Is the linker confused by polymorphism, or calls to (static) class methods?)

class ShM
{
public:
	ShM();
	ShM(char *name, unsigned int size = DEFAULT_SIZE);
	virtual ~ShM();
	bool open(char *name, unsigned int size = DEFAULT_SIZE); // returns whether opened successfully
	bool close();
	bool isRunning() const;
	void stop();
	void start();

	unsigned int getState() const;
	unsigned int getHour() const;
	unsigned int getStart() const;
	unsigned int getFinish() const;
	static unsigned int getInt(volatile unsigned char* buf);
	static void setInt(unsigned int x, volatile unsigned char* buf);
	static const unsigned int DEFAULT_SIZE = 16;
private:
	volatile unsigned char *vbuf;

	unsigned int getInt(unsigned int offset) const;
	void setInt(unsigned int x, unsigned int offset);
};

extern 'C' 
{
	void *createShM(char *name, unsigned int &size);
	void destroyShM(void * shm);
	void initShM(void *shm, unsigned int start, unsigned int finish);
	void setShMHour(void *shm, unsigned int hour);
	unsigned int getShMState(void *shm);
	void setShMState(void *shm, unsigned int state);
};
5 Oct 2006 1:05 #1116

Hi Clint

I have done some mixed coding using dlls (calling Fortran from VB6 and C++). In my experience all the problems when doing this are because of types not matching up across languages, especially at the fortran end because everything is passed by reference rather than by value.

without looking too hard I notice that there are unsigned integers in the extern C statement, these might be the problem since I believe there is no such type in Fortran, the other thing to look out for is the 'hidden' array length parameter when passing arrays and strings to fortran

to call the following fortran subroutine from C

subroutine example (message) character*() message write (,*) message end subroutine

the following declaration is needed

extern 'C' { void EXAMPLE (char *message, int length) }

where length is the length of the string being passed

a similer thing with arrays is required. this might be your problem as well. multidimensional arrays need a length for each dimension and are passed after all the other parameters.

I would suggest you work out what the call parameters for each subroutine need to be in turn using a trivial testing plan writeing stuff to the screen etc.

Also remember fortran is not type sensitve so having non capitalized function names is one more thing to go wrong!

I hope that is some help.

these trick issuse with mixed coding are what turned me on to .NET which makes a lot of this stuff trivial.

Carl

Please login to reply.