Arguments transfer Error in Winelib .dll.so

Open forum for end-user questions about Wine. Before asking questions, check out the Wiki as a first step.
Forum Rules
Locked
yueqishang
Newbie
Newbie
Posts: 4
Joined: Mon Apr 29, 2024 9:39 am

Arguments transfer Error in Winelib .dll.so

Post by yueqishang »

Hallo everyone,

I am currently working on a project where I need to use a Linux library as if it were a Windows DLL, similar to the process described in the Building Winelib DLLs section of the https://wiki.winehq.org/Winelib_User%27 ... nelib_DLLs.

In my project, I have several interface functions, such as:

Code: Select all

#project.cpp
typedef uint8_t            CHAR8;            /* ASCII‐coded 8‐bit character value */

extern "C" int getMyId(int type, CHAR8* pName, uint32_t* pId);
Firstly, I built my project as project.so, then I wrote a .spec file to describe all the interface functions of project.so, like this:

Code: Select all

## project.spec
@ stdcall getMyId(long ptr ptr) getMyIdProxy;
I also created a wrapper.cpp and wrapper.h file as described in the Winelib User's Guide:

Code: Select all

## wrapper.h

#include "myHeaders"
extern "C" {
	int getMyIdProxy(int type, CHAR8* pName, uint32_t* pId);
}

Code: Select all

## wrapper.cpp
extern "C" {
	int getMyIdProxy(int type, CHAR8* pName, uint32_t* pId) {
    		return getMyId(Type, pName, pId);
	}
}
After completing these steps, I ran the following command to generate a Makefile.

Code: Select all

winemaker --nosource-fix --dll --single-target project.dll --nomfc --lower-none -I /path/to/wrapper/ -L/path/to/project/myproject.so
I then used winebuild --def to generate a .def file from the .spec file I had written.

Code: Select all

#project.def 
; File generated automatically from project.spec; do not edit!

LIBRARY myproject.dll

EXPORTS
  getMyId=getMyIdProxy @1
  
I added this .def file to the LIBRARIES in the Makefile. The final Makefile looks like this:

Code: Select all

#Makefile
### Generated by Winemaker 0.8.4
###
### Invocation command line was
### /bin/winemaker --nosource-fix --dll --single-target myproject.dll --nomfc --lower-none -I /path/to/wrapper/ -L/path/to/porject/myproject.so


SRCDIR                = .
SUBDIRS               =
DLLS                  = myproject.dll
LIBS                  =
EXES                  =



### Common settings

CEXTRA                = -Wall
CXXEXTRA              =
RCEXTRA               =
DEFINES               =
INCLUDE_PATH          = -I \
			-I.
DLL_PATH              =
DLL_IMPORTS           =
LIBRARY_PATH          = -L/path/to/porject/myproject.so
LIBRARIES             = ./project.def


### myproject.dll sources and settings

myproject_dll_MODULE  = myproject.dll
myproject_dll_C_SRCS  =
myproject_dll_CXX_SRCS= winewrapper.cpp
myproject_dll_RC_SRCS =
myproject_dll_LDFLAGS = -shared
myproject_dll_ARFLAGS =
myproject_dll_DLL_PATH=
myproject_dll_DLLS    =
myproject_dll_LIBRARY_PATH=
myproject_dll_LIBRARIES=

myproject_dll_OBJS    = $(myproject_dll_C_SRCS:.c=.o) \
			$(myproject_dll_CXX_SRCS:.cpp=.o) \
			$(myproject_dll_RC_SRCS:.rc=.res)



### Global source lists

C_SRCS                = $(myproject_dll_C_SRCS)
CXX_SRCS              = $(myproject_dll_CXX_SRCS)
RC_SRCS               = $(myproject_dll_RC_SRCS)


### Tools

CC = winegcc
CXX = wineg++
RC = wrc
AR = ar


### Generic targets

all: $(SUBDIRS) $(DLLS:%=%.so) $(LIBS) $(EXES)

### Build rules

.PHONY: all clean dummy

$(SUBDIRS): dummy
	@cd $@ && $(MAKE)

# Implicit rules

.SUFFIXES: .cpp .cxx .rc .res
DEFINCL = $(INCLUDE_PATH) $(DEFINES) $(OPTIONS)

.c.o:
	$(CC) -c $(CFLAGS) $(CEXTRA) $(DEFINCL) -o $@ $<

.cpp.o:
	$(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $<

.cxx.o:
	$(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $<

.rc.res:
	$(RC) $(RCFLAGS) $(RCEXTRA) $(DEFINCL) -fo$@ $<

# Rules for cleaning

CLEAN_FILES     = y.tab.c y.tab.h lex.yy.c core *.orig *.rej \
                  \\\#*\\\# *~ *% .\\\#*

clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
	$(RM) $(CLEAN_FILES) $(RC_SRCS:.rc=.res) $(C_SRCS:.c=.o) $(CXX_SRCS:.cpp=.o)
	$(RM) $(DLLS:%=%.so) $(LIBS) $(EXES) $(EXES:%=%.so)

$(SUBDIRS:%=%/__clean__): dummy
	cd `dirname $@` && $(MAKE) clean

$(EXTRASUBDIRS:%=%/__clean__): dummy
	-cd `dirname $@` && $(RM) $(CLEAN_FILES)

### Target specific build rules
DEFLIB = $(LIBRARY_PATH) $(LIBRARIES) $(DLL_PATH) $(DLL_IMPORTS:%=-l%)

$(myproject_dll_MODULE).so: $(myproject_dll_OBJS) $(myproject_dll_MODULE:.dll=.def)
	$(CXX) $(myproject_dll_LDFLAGS) -o $@ $(myproject_dll_OBJS) $(myproject_dll_LIBRARY_PATH) $(myproject_dll_DLL_PATH) $(DEFLIB) $(myproject_dll_DLLS:%=-l%) $(myproject_dll_LIBRARIES:%=-l%)

Afterwards, I ran make and successfully generated a project.dll.so.

I am running a server.exe on my Linux machine using Wine, which loads the .dll.so wrapper as if it were a native Windows DLL. I renamed .dll.so to .dll and loaded it with the server as usual. However, the three parameters in the getMyId function are being transferred incorrectly.

Here are the results that I printed in each layer of the process:

What the server sends:

type: 32803
pShortname: ABC_DEF_HIJKLMN_OPQ2
pPduObjectId: 00007FFFFE1FECF4

What the proxy functions receive:

type: -1372395416 (random value)
pShortname: (null)
pPduObjectId: 0x140258ea0

This is obviously a memory-related error, but I'm not sure how to fix it. Any suggestions or ideas are welcome, thanks a lot :)
yueqishang
Newbie
Newbie
Posts: 4
Joined: Mon Apr 29, 2024 9:39 am

Re: Arguments transfer Error in Winelib .dll.so

Post by yueqishang »

Additional information:
We can already confirm that the Proxy function is being called correctly, as I print the parameters inside the Proxy function.
yueqishang
Newbie
Newbie
Posts: 4
Joined: Mon Apr 29, 2024 9:39 am

Re: Arguments transfer Error in Winelib .dll.so

Post by yueqishang »

One more thing:

Since the error occurs before the wrapper begins to function (input Parameters to Wrapper were wrong), the error should occur during the compilation of the wrapper by winegcc and wineg++ :?
Locked