Hi,

I made a dll and want to use it in my program.
I generated a inc-file. The inc and the libfile, made by generating the dll, were included in my programm.

include mydll.inc
includelib mydll.lib

MASM32 returns the error: unresolved external symbol _myfunction1@24

The function is named myfunction() and I want to invoke it via: invoke myfunction,0,0,0
With other program languages there is no problem to use all functions ? What's my error ?

Greetings,
Nordwind64
Posted on 2003-09-14 03:32:07 by Nordwind64
hmm _myfunction1@24

Doesn't that means that the function takes 6 parameters?hmmm
Posted on 2003-09-14 03:49:36 by roticv
Hi,

yes, you're right. It was only an example.

In program:
invoke myfunction,1,2,3,4,5,6

In incfile:
myfunction PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

But what's the error ?

Greetings,
Nordwind64
Posted on 2003-09-14 05:54:39 by Nordwind64
possibly youve forgotten to export this proc from your dll.
Posted on 2003-09-14 08:31:56 by japheth
Hi,

I have not forgotten, japheth.
The dll works fine with other program languages like purebasic.

Any ideas ?

Greetings,
Nordwind64
Posted on 2003-09-15 02:34:29 by Nordwind64
this is because MASM does not like procs with the names like _myfunction1@24

so what you can do is either patch the lib or the obj file and link it

patch and remove the @24 and the... i do this all the time but i dont use the macro from MASM i use elicz macros
from
http://elicz.cjb.net

also if possible remove the _ but i think to make that work you have to shift the name over to the left so that pointer does not point to a null value...

if you made this dll in C++ an easy way to fix this also is to make a def file with out the _ and the @24 and link it with the def file..
Posted on 2003-09-15 02:42:12 by devilsclaw
Another possibility is; when you create the DLL, you use a different language option, e.g. 'C' and you handled stack clearing by yourself (or maybe not). The point is the identifier may not have been mangled in a way that MS products expect with STDCALL convention. One simple way to check it is to use MASM32 utility l2inca.exe to generate a header file to compare and see if the generated header includes what you want.
Posted on 2003-09-15 04:23:52 by Starless
if you want... you can send me the dll and i can see if i can generate a working lib and inc for it...

my email is:http://www.asmcommunity.net/board/cryptmail.php?tauntspiders=in.your.face@nomail.for.you&id=ef0cf88c389cc24aadee46637a9bcb6b
if you send anything send it in a zip file.. or the antivirus on the server will reject it..
Posted on 2003-09-15 04:32:51 by devilsclaw
Hi,

devilsclaw, your link to the website goes to a clear window.

Starless, I use STDCALL, the dll was written in MASM32:

.386

.model flat, stdcall

option casemap :none ; case sensitive
[...]


This is an example of a function:


; ________________________________________________________________________________________________________________

GetColumns proc
; ????????????????????????????????????????????????????????????????????????????????????????????????????????????????
push ebp
mov ebp,esp

invoke SendMessage,[ebp+8],LVM_GETHEADER, 0, 0
invoke SendMessage,eax,HDM_GETITEMCOUNT, 0, 0

pop ebp
ret 4 ;Only one parameter
GetColumns endp


I use , , ect. for parameters.
Does this method produces the error ? Works fine with other languages...

Greetings,
Nordwind64
Posted on 2003-09-15 06:46:44 by Nordwind64
Anyway by the looks of your code I do not see why you need to set up a stack frame. Just use the parameters relative to esp. AFAIK it had been working fine for me, expect that I used the parameters relative to esp. Anyway did you use


OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

?
Posted on 2003-09-15 07:02:40 by roticv
Hi,

roticv: Thank you!
Yes I tried it, but it don't work.
You 're right, the stack frame is not nessesary, but should not generate the error...

Any other help ?

Greetings,
Nordwind64
Posted on 2003-09-15 08:01:15 by Nordwind64
Originally posted by Nordwind64
Does this method produces the error ?

Yes, w.r.t. name mangling, hence you have the problem of linking. Look into your import library. You will not find _GetColumns@4 or __imp__GetColumns@4 in the import library, even if you coded your function as STDCALL. You will find only _GetColumns and __imp__Getcolumns. That is because MASM mangles the name based on the argument(s) given in the PROC line. To correct the situation, use this


GetColumns proc the_argument:dword
...
GetColumns endp

And, of course, if you actually don't use the argument(s) by name, you can always use what roticv suggested earlier.

The important part is that you have list all the arguments (with some unsual name if you don't want to use stack frame at all) to correctly produce the mangled name.

Or, you mangle the name yourself, e.g.


option language:syscall
_GetColumns@4 proc
...
_GetColumns@4 endp
Posted on 2003-09-15 08:12:16 by Starless
watch mydll.lib with a hex editor. It should give you some clues about the correct name. You should find
"_myfunction1@24" string there, as well as "__imp_myfunction1@24".

Or use dumpbin for that task

Japheth
Posted on 2003-09-15 08:12:21 by japheth
Hi,

Starless:

GetColumns proc the_argument:dword

...
GetColumns endp


Yes, that works !
I tested it yesterday, but the problem is, there are almost 100 function in the dll and I have to rewrite all proc lines.
Twice, I cannot use ,,...etc., I must change it to arg1, arg2,... Much work !
I wondered, if there exists another possibility ?

japheth:
No, sorry. ALL functions are ending with @0, independent how many parameter the function works with...

_ASortListview@0

__imp__ASortListview@0
_ReadFileQuick@0
__imp__ReadFileQuick@0
_SetItemsFromMem@0
__imp__SetItemsFromMem@0
[...]


Hmm...

Greetings,
Nordwind64
Posted on 2003-09-15 13:19:50 by Nordwind64
my link is a email now a web page..
Posted on 2003-09-15 13:39:49 by devilsclaw
Yes, that works !
I tested it yesterday, but the problem is, there are almost 100 function in the dll and I have to rewrite all proc lines.
Twice, I cannot use ,,...etc., I must change it to arg1, arg2,... Much work !
I wondered, if there exists another possibility ?

1. If you want MASM to generate the mangled names, you have to change the proc line.

2. You can still use ,... to access your arguments. The trick is either you follow what roticv said earlier, or you remove push ebp/mov ebp,esp and leave or mov esp,ebp/pop ebp from your functions.

3. Now that the arguments are nothing but automated ebp-based memory reference, your argument names need not be meaningful if you don't access them by name. Say, myfunction1 takes 6 args, and you coded it


myfunction1 proc
...
myfunction1 endp

then, to generated the correctly mangled name, you might want to try this (of course, you decide how to avoid name space clash in your project as a whole)


myfunction1 proc _1:dword,_2:dword,_3:dword, \
_4:dword,_5:dword,_6:dword
myfunction1 endp

You can automate this process with perl, or any other text processing tools. If you don't know how to use them, you are out of luck and you have to edit each and every file manually.

4. Or, mangle the name yourself. See my previous post for how to do that. This could be much easier for you to do if you have to edit many functions. Then again, you have to be careful about how to use the header file.
Posted on 2003-09-15 17:44:30 by Starless
Hi,

there is a number 5...

5. I use externdef for functions instead of PROTO and write my own invoke macro...

externdef _imp__CreateListview@0:PTR pr0

CreateListview equ <_imp__CreateListview@0>

[...]

_invoke CreateListview,hWin,hInstance,0,eax,-1,35h


That works perfect now.
Have much thanks - my friends - for helping me alot !!!

Greetings,
Nordwind64
Posted on 2003-09-15 23:36:44 by Nordwind64