Trouble with DLL stdcall and no name decoration

General FreeBASIC programming questions.
Post Reply
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Trouble with DLL stdcall and no name decoration

Post by D.J.Peters »

I try to write a 32-bit DLL plugin for a game with FreeBASIC
but if the plugin are loaded the game crashed.

It must be __stdcall without name decoration.

plugin_bas.dll create a beep if loaded than the game crashs.

plugin_c.dll create a beep if loaded and while it runs without any problem.

Any idea why C++ works but not the FreeBASIC build ?

Joshy

file: plugin_bas.bas

Code: Select all

Extern "Windows-MS" ' <--- using stdcall without @XX name decoration

sub Start (byval pForm as any ptr) export
  beep()
end sub

sub Finalize ()  export
  beep()
  beep()
end sub

sub AccessVariable (byval Index as ushort, byval Value as single ptr, byval blnWrite as ubyte ptr) export
end sub

sub AccessTrigger (byval Index as ushort, byval blnActive as ubyte ptr) export
end sub

end extern
the same in C++ works
file: plugin_c.h

Code: Select all

#ifndef __PLUGIN_H__
#define __PLUGIN_H__

#ifdef WIN32
  #include <windows.h>
#else
  #error Target must be WIN32 !
#endif

extern "C"  void __stdcall Start(void* form);
extern "C"  void __stdcall AccessVariable(unsigned short varindex, float* value, bool* write);
extern "C"  void __stdcall AccessTrigger(unsigned short triggerindex, bool* active);
extern "C"  void __stdcall Finalize();
#endif // __PLUGIN_H__
file: plugin_c.cpp

Code: Select all

#include "plugin_c.h"

void  Start(void* form) {
  Beep(440,500);
}
void  AccessVariable(unsigned short varindex, float* value, bool* write) {
  Beep(440,10);
}
void  AccessTrigger(unsigned short triggerindex, bool* active) {
}
void  Finalize() {
  Beep(220,500);
}
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Trouble with DLL stdcall and no name decoration

Post by D.J.Peters »

Of course the game it self isn't compiled with debug infos -g
but if I run the game with gdb and the BASIC plugin crashes stacktrace prints out "corrupt stack frame"

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Trouble with DLL stdcall and no name decoration

Post by D.J.Peters »

Locks like the beep command works from sub Start but than the game crashed while loading textures.
Can it be that a FreeBASIC DLL change the current PATH or any environment var of the calling main process ?

Joshy
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Trouble with DLL stdcall and no name decoration

Post by MrSwiss »

"corrupt stack frame"
I'd check 2 things (second because, I don't know the size(in bytes) of bool in C).
1) the UByte Ptr (correct ? or rather Boolean Ptr ?)
2) is the size of the C bool correct for byte/boolean in FB ?
If a C bool is, e.g. sizeof(int/uint), you'll have to use: Long/ULong Ptr in FB.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Trouble with DLL stdcall and no name decoration

Post by D.J.Peters »

A pointer is a pointer and I don't touch it
so it plays no rule dose it point to boolean, bool=byte, int or long you know ?
on stack a pointer is 4 byte on 32-bit.

Joshy
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Trouble with DLL stdcall and no name decoration

Post by MrSwiss »

Well, I was actually referring to: size of allocated memory (to Ptr),
not the Ptr size, itself.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Trouble with DLL stdcall and no name decoration

Post by D.J.Peters »

Why FB access (read) the stack and create a temporary var in the stack space if the sub's are empty ?

Joshy

Code: Select all

Extern "Windows-MS" ' stdcall no @# decoration
sub AccessVariable (byval Index as ushort, byval Value as single ptr, byval blnWrite as ubyte ptr) export
end sub
sub AccessTrigger (byval Index as ushort, byval blnActive as ubyte ptr) export
end sub
end extern

Code: Select all

L6:
	.globl	_AccessVariable
	.def	_AccessVariable;	.scl	2;	.type	32;	.endef
_AccessVariable:
	push	ebp
	mov	ebp, esp
	sub	esp, 4
	mov	eax, DWORD PTR [ebp+8]
	mov	WORD PTR [ebp-4], ax
	nop
	leave
	ret	12
L8:
L9:
	.globl	_AccessTrigger
	.def	_AccessTrigger;	.scl	2;	.type	32;	.endef
_AccessTrigger:
	push	ebp
	mov	ebp, esp
	sub	esp, 4
	mov	eax, DWORD PTR [ebp+8]
	mov	WORD PTR [ebp-4], ax
	nop
	leave
	ret	8
The C++ DLL does not access the stack and works

Code: Select all

	.p2align 4,,15
	.globl	AccessVariable
AccessVariable:
	ret	$12
	.p2align 4,,15
	.globl	AccessTrigger
	.def	AccessTrigger;	.scl	2;	.type	32;	.endef
AccessTrigger:
	ret	$8
SARG
Posts: 1757
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Trouble with DLL stdcall and no name decoration

Post by SARG »

Hi,

When accesstrigger (same with accessvariable) is called Index is put on stack as DWORD then in the sub it's put in another location as a WORD....
By the way with GAS only prologue and epilogue, no code added.

Tested in a simplier way.

Code: Select all

sub AccessTrigger (ByVal Index as UShort)
Print index
end Sub
AccessTrigger(10)

Code: Select all

	.globl	_AccessTrigger
	.def	_AccessTrigger;	.scl	2;	.type	32;	.endef
_AccessTrigger:
	push	ebp
	mov	ebp, esp
	sub	esp, 40
	mov	eax, DWORD PTR [ebp+8]
	mov	WORD PTR [ebp-12], ax    <---- stored as a WORD
L5:
	mov	eax, DWORD PTR [ebp-12]
	and	eax, 65535
	mov	DWORD PTR [esp+8], 1
	mov	DWORD PTR [esp+4], eax
	mov	DWORD PTR [esp], 0
	call	_fb_PrintUShort@12
	sub	esp, 12
	leave
	ret	4

Code: Select all

	mov	DWORD PTR [esp], 10  <----- stored as DWORD
	call	_AccessTrigger
	sub	esp, 4
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Trouble with DLL stdcall and no name decoration

Post by D.J.Peters »

@SARG good find you are right -gen gcc creates a temporary var and read the index from stack and -gen gas creates only the prolog and epilog of the sub.

The problem are fb calls inside the created dll _main and than from _main are __main called also.
Looks like __main setup a kind of environment for the dll.

if the gane calls the C dll Start() sub I get the beep
and I see this 3 massages on the game loader dialog
"loading environment traffic"
"loading textures"
"loading AI"
then the game starts and every render frame AccessVariable, AccessTrtigger are called

if the gane calls the FB dll Start() sub I get the beep
and I see only 2 massages on the game loader dialog
"loading environment traffic"
"loading textures"
then the game crashes with an entry in a log file "can't read texture".

I don't know why the game can't find or read the texture after the FB created dll are loaded.

May be the FB created dll changes the path of the caller or overwrites a part of the environment vars I don't know :-(

Joshy
marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Trouble with DLL stdcall and no name decoration

Post by marcov »

If code like _start ends up in dllmain (or called via dllmain), there are limitations what is allowed there, see https://blogs.msdn.microsoft.com/oldnew ... 0/?p=40873
SARG
Posts: 1757
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Trouble with DLL stdcall and no name decoration

Post by SARG »

Have you tried other calls of subs without parameters ? subs contained in the dll..... instaed of accesstrigger

If possible post reduced code giving the error ?

I don't understand what you wrote :
"The problem are fb calls inside the created dll _main and than from _main are __main called also.
Looks like __main setup a kind of environment for the dll."
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Trouble with DLL stdcall and no name decoration

Post by D.J.Peters »

@SARG the game OMSI a bus-driver simulation and call's the sub's inside a plugin dll.

So if the subs are empty there isn't any reason while the FB build dll crashes and the C/C++ dll works fine here.

If you compile any stuff with FreeBASIC you can view the created assembler list with the command line option -RR
fbc -RR stuff.bas

in case of a DLL
fbc -RR -dll stuff.bas

you get the file stuff.asm with calls to _main and __main also
(I don't know what this calls do inside the DLL)

The FB created dll is ~18KB the C/C++ dll only ~10K

bla bla bla :-)

I don't have time for this kind of trouble so I will write my OMSI pluigin in C/C++ know.

How ever thank you all for you help and support.

Joshy
Post Reply