I'm having a little trouble adding masm32 lib to a project. I had the following which worked without problems-
.486
.model Flat, Stdcall
option Casemap :None ; case sensitive
include Windows.inc
uselib MACRO libname
include libname.inc
includelib libname.lib
ENDM
uselib user32
uselib kernel32
uselib shell32
uselib comctl32
uselib comdlg32
uselib gdi32
I then added masm32 to the list0
uselib masm32 ; for debug
and got the following errors-
Dip.obj : error LNK2001: unresolved external symbol _run_synch_process_ex@8
masm32.lib(BitmapFromFile.obj) : error LNK2001: unresolved external symbol _OleLoadPicturePath@24
masm32.lib(BitmapFromMemory.obj) : error LNK2001: unresolved external symbol _OleLoadPicture@20
masm32.lib(QSORTA.obj) : error LNK2001: unresolved external symbol _SysAllocStringByteLen@8
masm32.lib(QSORTD.obj) : error LNK2001: unresolved external symbol _SysAllocStringByteLen@8
masm32.lib(a2wc.obj) : error LNK2001: unresolved external symbol _SysAllocStringByteLen@8
masm32.lib(QSORTA.obj) : error LNK2001: unresolved external symbol _SysFreeString@4
masm32.lib(QSORTD.obj) : error LNK2001: unresolved external symbol _SysFreeString@4
F:\WinAsm\Progs\Dip\Dip.exe : fatal error LNK1120: 5 unresolved externals
I've use this code in many other programs with no problem so am at a loss for an explanation.
Searching for some of these, I added the line-
uselib oleaut32
just to see what would happen. There is no reason I can see why I would need this library, but I tried it anyway. Then I just got this error-
Dip.obj : error LNK2001: unresolved external symbol _run_synch_process_ex@8
Anyone know what is going on here? I suspect it is some naming problem in my code conflicting with the library routines, but I can't seem to find it in the 3000 lines of code :(
Are you sure the masm32.lib is in the search path? Or at least copied to where the other *.lib files are?
Regards, P1 :8)
Dang, I looked for a long time before posting. What was happening is I already had masm32 lib declared much farther down in the code where it didn't belong :red Somehow it was in a section I thought was inactivated. So the problem was having it included twice! Duh..... someday I'll learn :'(
I have this problem some weeks ago too. My solution was in change including order. (I don't remember, if masm32 was first). Then it was OK.
Hi Jimg,
You have to use CATSTR or @CatStr to concatenate strings :
Quote
String Directives and Predefined Functions
CATSTR
Concatenates one or more strings to a single string.
These directives assign a processed value to a text macro or numeric equate. For example, the following lines
num = 7
newstr CATSTR <3 + >, %num, < = > , %3 + num ; "3 + 7 = 10"
assign the string "3 + 7 = 10" to newstr. CATSTR and SUBSTR assign text in the same way as the TEXTEQU directive. SIZESTR and INSTR assign a number in the same way as the = operator. The four string directives take only text values as arguments. Use the expansion operator (%) when you need to make sure that constants and numeric equates expand to text, as shown in the preceding lines.
Each of the string directives has a corresponding predefined macro function version: @SubStr, @InStr, @SizeStr, and @CatStr. Macro functions are similar to the string directives, but you must enclose their arguments in parentheses. Macro functions return text values and can appear in any context where text is expected. The following section, "Returning Values with Macro Functions," tells how to write your own macro functions. The following example is equivalent to the previous CATSTR example:
num = 7
newstr TEXTEQU @CatStr( <3 + >, %num, < = > , %3 + num )
http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_09.htm
??????!? :dazzled:
Hi Vortex-
You usually post very helpful responses, however in this case it went completely over my head. How does catstr apply to my original question??
<untested>
uselib MACRO libname
include @CatStr(%libname , <.inc>)
includelib @CatStr(%libname , <.lib>)
ENDM
Vortex,
An interesting idea. :U
Hmmm-
I have been using that uselib macro forever with no problems, why would catstr be required here?
Also, there's something slightly wrong with your suggestion as I get
F:\WinAsm\Progs\Dip\Dip.asm(23) : fatal error A1000: cannot open file : @CatStr(%user32 , <.inc>)
It should be
% include @CatStr(&libname , <.inc>)
% includelib @CatStr(&libname , <.lib>)
but the real problem, as I metions above, is that I had masm32.lib declared twice. And it doesn't seem worth putting in ifndef, etc. to get around the problem, better to just fix the code.
Or am I still being really dense and missing the point here?
This roughie works.
inclib MACRO barename
LOCAL incc,libb
incc equ <include >
libb equ <includelib >
incc CATSTR incc,<\masm32\include\>,<barename>,<.inc>
libb CATSTR libb,<\masm32\lib\>,<barename>,<.lib>
% incc
% libb
ENDM
inclib kernel32
inclib user32
inclib gdi32
Ok, now I get it. You guys are just trying to confuse me with the most complicated way of doing something simple. It may take awhile but eventually I catch on.
No, that would require decoding the (mangled) filename with a polyalphabetic substitution cipher. :)
Quote from: Jimg on July 29, 2005, 03:33:21 PM
Searching for some of these, I added the line-
uselib oleaut32
just to see what would happen. There is no reason I can see why I would need this library, but I tried it anyway. Then I just got this error-
Dip.obj : error LNK2001: unresolved external symbol _run_synch_process_ex@8
The masm32 library includes functions from Ernie's ImageLib, which uses oleaut32.dll. That's why you need that import library as well - try it using bare "include" and "includelib" statements if you don't believe me.
The last error you got is probably another import required by the masm32 library.
But I didn't need it! The whole problem was having two includes for masm32.inc
I still have no idea why this would cause the errors I got just because I had the two includes, but I certainly know the solution!
Jimq,
Usually, it has been my experience, that if you accidently include a library twice you will get those errors because the assembler will toss out BOTH instances. You had already solved your problem but there was an observation that the macro could be written in a more robust sort of way. That is all.
My recommendation is that includes and includelibs should only be at the start of the source file so as to avoid these type of accidents. Good job solving your problem, though. As far as ifndef goes, I totally agree with you. Just get it right and there is no need. I have seen some users post code with 5 or 6 .ASM files; these are error prone for just this reason, and when you get a vague sort of error it can drive you out of your gourd.
Paul
I think regardless of how robust the macro was written it would still require the programmer to get the input right!
Jimg, I have used macros similar to that before for generating large redirect-DLLs and it works fine. Just ignore these guys trying to bloat your software :cheekygreen:
hello,
I try to modify the macro
LIBRAIRIE MACRO nomsansext:VARARG
local inclus,librairie
FOR nom,<nomsansext>
inclus CATSTR <include \masm32\include\> ,<nom>,<.inc>
librairie CATSTR <includelib \masm32\lib\>,<nom>,<.lib>
% inclus
% librairie
ENDM
ENDM
using it LIBRAIRIE user32,kernel32,perso32,imagehlp,masm32
It's work , but the masm32 made an "internal error" with MakeIP MACRO,put the macro in comments
and there is no more problem,
WHY ????????????????
ToutEnMasm
:U
This is the version of uselib that I like and will use from now on. It has been tested.
uselib MACRO namelist:VARARG
FOR item, <namelist>
include \masm32\include\item.inc
includelib \masm32\lib\item.lib
ENDM
ENDM
uselib kernel32,user32,comctl32,wsock32,comdlg32
It is similar to ToutEnMasm's version but uses the easy to understand methods employed by Jimg.
ToutEnMasm,
I just noticed the macro problem, also. Evidently the assembler cannot handle that.
Hutch,
Would you consider moving that macro to macro.asm? I am going to do it on my machine for sure.
EDIT: Actually, I just noticed it already exists in dlglib.inc, so I just deleted the macro from masm32.inc
Paul
Hello,
I agree it is more simple , but there is the same bug
\masm32\include\masm32.inc(172) : fatal error A1016: Internal Assembler Error
with the masm32.inc,makeip isn't allowed.I try it with ml 6.15 an 7.10.
ToutEnMasm
Hutch is going to move that macro to macro.asm in the next version so no more problem :U
Paul
Something I am missing here, there are two seperate macros involved and I don't know what the relationship is. Paul identified a duplicate I had with the pre-built dialog code so I have removed it so there is only one copy which is still in te masm32.inc file at the moment. Then there are the various versions of macros that load both the include file and the library in one macro call. What i don't know is how the two are related.
Can someone fill me in on what is happening here ?
Hutch,
There is an odd error that is generated when a macro loads an include file that loads a macro. The error message is VERY vague and says that there is an internal assembler error. If the macro that is in masm32.inc is remmed out the error disappears. I don't think this has anything to do with your project but appears to be some sort of limittation of the preprocessor.
This is the error that is generated...
Quote
Assembling: ZipDLL.asm
\masm32\include\masm32.inc(180) : fatal error A1016: Internal Assembler Error
This is the macro I am using...
include \masm32\include\windows.inc
uselib MACRO namelist:VARARG
FOR item, <namelist>
include \masm32\include\item.inc
includelib \masm32\lib\item.lib
ENDM
ENDM
uselib kernel32,user32,masm32,comctl32,wsock32,comdlg32
Now, my macro is a compile time macro but MakeIP is a runtime macro. That is the only difference that I can think of. This means my macro is 'used' by the assembler whereas MakeIP is not but perhaps the assembler 'thinks' that it is in the firat pass and improperly expands it? I am just guessing so I will await your answer. You are the preprocessing guru, not me!
If you need a test piece I can provide one. If I remove the MakeIP macro or rem it out, the error disappears.
Paul
Paul,
Its a problem with a transformation in the macro FOR loop. I put the macro directly into macros.asm and removed the IP macro and it fails on other macro calls. I will see if I can get it working but the included backdslash characters are clashing with masm line continuation characters.
Hello,
After some more testing,macros are not allowed in the files loaded by FOR .... LOOP.
BackSlash is allowed in the line
include macro.inc
include \masm32\include\windows.inc
LIB kernel32,gdi32,user32,Comctl32,masm32,comdlg32,shell32,oleaut32,\
ole32,msvcrt,imagehlp,perso32
ToutEnMasm
Hutch,
Toutenmasm makes sense here. As far as the backslash is concerned, it is not the problem at all and never was. The problem still occurred when I tried putting the paths into the environment and removing them from the macro so it was as follows...
include \masm32\include\windows.inc
uselib MACRO namelist:VARARG
FOR item, <namelist>
include item.inc
includelib item.lib
ENDM
ENDM
uselib kernel32,user32,masm32,comctl32,wsock32,comdlg32
Thank you for the help, though, and I have no doubt you will figure it out. When it comes to macros, I am out of my depth. I just write them and expect the ornery things to cooperate. ::)
I will have to read up on FOR loops. Does anyone know of a good document for macros (advanced, perhaps)?
Paul
Paul,
This appears to work fine.
include \masm32\include\windows.inc
include \masm32\macros\macros.asm
; -----------------------------------------------
uselib MACRO args:VARARG
LOCAL acnt,buffer,var,lbl,libb,incc,buf1,buf2
acnt = argcount(args)
incc equ <include \masm32\include\>
libb equ <includelib \masm32\lib\>
var = 1
:lbl
buffer equ getarg(var,args)
buf1 equ <>
buf1 CATSTR buf1,incc,buffer,<.inc>
buf1
% echo buf1
buf2 equ <>
buf2 CATSTR buf2,libb,buffer,<.lib>
buf2
% echo buf2
var = var + 1
IF var LE acnt
goto lbl
ENDIF
ENDM
Hutch
I cannot get that to work. It produces the following errors...
Quote
Assembling: ZipDLL.asm
ZipDLL.asm(41) : error A2008: syntax error : ,
uselib(2): Macro Called From
ZipDLL.asm(41): Main Line Code
ZipDLL.asm(41) : fatal error A1000: cannot open file : \masm32\include\getarg(??001B,kernel32,user32,masm32,comctl32,wsock32,comdlg32).inc
uselib(41): Macro Called From
ZipDLL.asm(41): Main Line Code
It evidently does not like the commas in the following line...
uselib kernel32,user32,masm32,comctl32,wsock32,comdlg32
So I removed the commas and was left with this...
Quote
Assembling: ZipDLL.asm
ZipDLL.asm(41) : fatal error A1000: cannot open file : \masm32\include\getarg(??001B,kernel32 user32 masm32 comctl32 wsock32 comdlg32).inc
uselib(41): Macro Called From
ZipDLL.asm(41): Main Line Code
Any thoughts?
Paul
Paul,
Give tis a blast, its the next macros.asm file. Make sure you include BOTH Windows.inc and the macro file before you call the macro.
[attachment deleted by admin]
Hutch,
That works VERY well. Thank you very much. The following is the start of my code...
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\macros\macros.asm
uselib kernel32,user32,comctl32,wsock32,comdlg32
I will now take some time to dissect your macro so that I will fully understand how it works. I like the simplicity of its utilization. It is a nice compliment to the masm32rt.inc which handles a wide range of applications. This is a nice way of handling any that drop through the cracks for whatever reasons.
Paul
Maybe I miss something, but what actually causes the Internal Assembler Error, guys?
When I remove the MakeIP macro from masm32.inc, it works well. Too bad, I can't see what is wrong with MakeIP :(
Hello,
I try to explain another time,
The macro it's an easy way for loading libraries and there Prototypes.
When there is only prototypes in the kernel32.inc, for example,the macro work well.
But the file masm32.inc have a macro in it,MakeIP,and ml have an internal error with it.
If we put other's macros in the include files join to the libraries,the same error occure.
The more simple macro is this one,that work very well.
ToutEnMasm
LIB MACRO nomsansext:VARARG
FOR nom,<nomsansext>
include \masm32\include\nom.inc
includelib \masm32\lib\nom.lib
ENDM
ENDM
Thanks ToutEnMasm, I got it finally :red
BTW, ML 8.00 beta2 contains the same bug:
Quote
Assembling: tmp.asm
MASM : fatal error A1016: Internal error
Microsoft (R) Macro Assembler Version 8.00.50215.44
Copyright (C) Microsoft Corporation. All rights reserved.
It also prints nice crash dump...
The internal assembly error is caused by using a for loop, and within that loop including a file that has a macro in it. It has nothing to do with MakeIP itself, just the fact that it is a macro. This is a bug in masm itself. Moving MakeIP solves the problem for masm32.inc, but including another library with macros, for example debug, brings the problem right back. Too bad we have to create our own loop to get around the problem.
Opps, previous answer while I was editing.
Re,
You can send this internal error to microsoft.The beta version of ml (visual studio) have a special option to made It.
ToutEnMasm
You also get the same error using a while loop in place of the manual inc/test/goto in the new macro.
This probably has something to do with this from the masm documentation:
QuoteThe assembler performs parameter substitution at each level of
nesting. Therefore, you must add an extra ampersand before or
after a macro parameter for each level of MACRO nesting or
FOR/FORC/REPEAT/WHILE nesting.
The new uselib macro could be cleaned up a bit though-
uselibs MACRO args:VARARG
LOCAL acnt,buffer,var,lbl,buf1
acnt = argcount(args)
var = 1
:lbl
buffer equ getarg(var,args)
buf1 CATSTR <include \masm32\include\>,buffer,<.inc>
buf1
buf1 CATSTR <includelib \masm32\lib\>,buffer,<.lib>
buf1
var = var + 1
IF var LE acnt
goto lbl
ENDIF
ENDM
re,
I try your macro
minus.asm(42) : fatal error A1000: cannot open file : \masm32\include\getarg(??0002,kernel32,gdi32,user32,Comctl32,masm32,comdlg32,shell32,oleaut32,ole32,msvcrt,imagehlp,perso32).inc
I try my best english,but I couldn't understand wat is an extra ampersand ? (in the doc you copy)
ToutEnMasm
That was the problem with the first version from Hutch. Did you do the change correctly? Jimg's version works fine on my machine.
Make sure you have replaced your version of macro.asm with the one Hutch posted in this topic. Just pasting Jimg's macro into the old macro.asm will not work.
hth,
Paul
I'm probably wrong about the ampersand thing. It seemed possible at the time, but perhaps not now.
Also, you did notice I changed the name of the macro in the one I posted (uselibs vs. uselib)?
And Macros.asm is required for both of these, also.
Karel,
There is nothing wrong with the makeIP macro, its a side effect of using the "\" character in a path inside a FOR loop, thats why I changed the loop to a label with a goto instead.
OK,
The last macros.asm (in the image of masm32) is needed.
uselib use two macros argcount and getarg to replace the loop FOR ....
All is clear.
Now it's work,without internal error.
ToutEnMasm
QuoteThere is nothing wrong with the makeIP macro, its a side effect of using the "\" character in a path inside a FOR loop, thats why I changed the loop to a label with a goto instead.
The original slash problem is easily fixed by putting in a double slash (\\masm32\\include\\) etc.
The real problem is still doing an include of a file inside a for loop where the the included file contains macros.
Jimg,
Could you please point me to the documentation that talks about the problem of running a macro from within a FOR loop?
Thank you in advance and thank you for your macro optimizations.
Paul
Hi Paul-
Look in masm32.hlp, topic= Nested Macros
Here's another one for you:
We could also get rid of the CATSTRs by making our own getarg internally. That way we can use the result directly-
uselibs MACRO args:VARARG
LOCAL acnt,buffer,var,lbl,cnt
acnt = argcount(args)
var = 1
:lbl
cnt = 0
FOR arg, <args>
cnt = cnt + 1
IF cnt EQ var
buffer TEXTEQU <arg> ;; set "txt" to content of arg num
EXITM
ENDIF
ENDM
%include \\masm32\\include\\buffer.inc
%includelib \\masm32\\lib\\buffer.lib
var = var + 1
IF var LE acnt
goto lbl
ENDIF
ENDM
Or we could skip the loop in a loop and any dependency on macros.asm by just using instr and substr:
uselibs MACRO args:VARARG
LOCAL var,st,tp,lbl
tp = 0
:lbl
st = tp + 1
tp instr st,<args, >,<,>
if tp eq 0
exitm
endif
var substr <args>,st,tp-st
%include \\masm32\\include\\var.inc
%includelib \\masm32\\lib\\var.lib
goto lbl
ENDM
This is actually classic MASM bug...
http://win.asmcommunity.net/board/index.php?topic=14102.0