Pelles C forum
Pelles C => General discussions => Topic started by: CCoder on April 07, 2007, 03:50:43 PM
-
I will start in this fourm since I am not sure if this a bug. I am trying to set up a program test for MASM ASM to call C. I am using a Batch File with the following:
......
C:\MASM32\bin\ml.exe /c /coff /Cp /Ic:\masm32\include AsmCallC.asm
REM Pelle's C
echo Compile C Code
"C:\Program Files\PellesC\Bin\pocc.exe" /Ox /Ot /I "C:\Program Files\PellesC\include" AsmTest.c
.......
echo Link C Code
"C:\Program Files\PellesC\Bin\polink.exe" @PellesC.rsp AsmCallC.obj AsmTest.obj
The PellesC.rsp file is:
/RELEASE
/SUBSYSTEM:CONSOLE
/VERBOSE
"/LIBPATH:C:\Program Files\PellesC\Lib"
"/LIBPATH:C:\Program Files\PellesC\Lib\Win"
pocrt.lib
Everything compiles and links fine with no problem when I run the batch file but I when I start the AsmCallc.exe program I get a message "This application has failed to start because pocrt.dll was not found. Re-installing the application may fix this problem."
As near as I can tell from my research my compile is using single threaded lib calls so I am unclear why the pocrt.dll is needed. If I copy the pocrt.dll into the working directory then the app runs normally. If I run the link with /VERBOSE I get the following:
Searching C:\Program Files\PellesC\Lib\pocrt.lib
Found _fprintf
pocrt.lib(pocrt.dll)
It looks like the linker is pulling in the pocrt.dll when I want it to pull in the .lib file. Any thoughts on what I am missing? Also, why do I link my ASM code with POLINK and not link.exe?
-
You could use static crt.lib instead.
-
You have pocrt.lib in 'PellesC.rsp', which will (indirectly) reference pocrt.dll. pocrt.dll is Pelles C multi-threaded C runtime library in a separate DLL. You can also link with crt.lib, which is Pelles C single threaded C runtime static library, or crtmt.lib, which is Pelles C multi-threaded C runtime static library.
The static libraries will put all C runtime code in the executables, so no extra DLL is needed. The DLL version is useful to make the executables smaller, but this means that pocrt.dll must be available when the program is run. If you copy the program to a different computer, pocrt.dll must be copied too... (which can be a pain sometimes...)
-
Pelle,
Thank you for your help. I hate to ask for more help when you have just helped me out already but I am really confused. I changed the .rsp file to specify crt.lib and I am able to compile and link things with no problem but when I run the .exe it just hangs. No output is written to the console. I have looked @ this in OllyDBg and it seems to get stuck in a loop when calling the ReadConsoleInputA API function. I don't think this is an issue with the code (C or ASM) because I was able to get it work when I copied and linked with the pocrt.dll.
I know there is something missing here but I am stumped about what to try next. If you have any thoughts please advise me.
I have attached the code (C and ASM), the make file and the .exe in the zip file.
Hope someone can help...
-
CCoder,
Since the entry point (main) is in the asm file, the C Run-time is not getting initialized properly. This is only a problem when the CRT is linked statically. See "Program startup: the true story" in the Pelles C Help file.
-
That helps a little but I am still unclear what to do next. So mainCRTstartup is called before my main (ASM) proc and it initializes the C Runtime library. So what do I need to do to have mainCRTStartup called before my main PROC in ASM?
I tried using /ENTRY:crtMainStartup but I get an unresolved symbol for _main.
-
CCoder,
There is a way, but it's undocumented.
; AsmCallC.asm
.486
.MODEL FLAT,STDCALL
OPTION CASEMAP:NONE
INCLUDE windows.inc
INCLUDE kernel32.inc
INCLUDELIB kernel32.lib
asmPrintFunc PROTO C :PTR BYTE
WaitKey PROTO C
; undocumented
;--------------------------------------------
__bheapinit PROTO C ; will return a non-zero value on success, otherwise zero -- for malloc() etc.
__ioinit PROTO C ; will not return anything -- for I/O handles etc.
;--------------------------------------------
.DATA
msgPrint BYTE "Test Call from AsmCallC to asmPrintFunc",13,10,0
.CODE
start:
; undocumented way to initialize a statically linked C Run-Time Library
;--------------------------------------------
INVOKE __bheapinit
test eax, eax
jz @F
INVOKE __ioinit
;--------------------------------------------
INVOKE asmPrintFunc, ADDR msgPrint
INVOKE WaitKey
@@:
INVOKE ExitProcess, 0
END start
I ran into the same problem a while back. http://www.masm32.com/board/index.php?topic=2670.0 (http://www.masm32.com/board/index.php?topic=2670.0)
-
Yes, this looks OK as minimal init of the single threaded library (crt.lib). For the multi-threaded version of the static library (crtmt.lib), there is an additional call (after __bheapinit, before __ioinit):
__mtinit PROTO C ; will return a non-zero value on success, otherwise zero
INVOKE __mtinit
test eax,eax
jz oops
I will think about it, but perhaps I will include the sources of the startup code in the future...
-
Pelle,
Thanks for the additional tidbit about initializing crtmt.lib. I had almost forgotten about how the static CRT initialization works, but CCoder jogged my memory, and I had saved the example code. Maybe just expand on the "Program startup: the true story" help subject.
-
Thank You, Thank You, Thank You!
The example you gave works just fine in the sample I coded. I appreciate the help, it's given a little better understanding of how things work "under the hood". ;D Though I will probably stick to using pocrt.dll simply because it's a little safer.
Just to make sure I am understand things properly I need the code sample when:
1. I have an ASM program calling a C program.
2. The ASM program is the entry point of the application (I.E. there is no C main() which calls ASM )
3. The CRT.LIB or CRTMT.LIB is statically linked into the application.
Thanks!
-
Greg,
No problem.
Yes, updating the help file will work too. Some C compiler distributions comes with source code for the startup code, in case someone wants to modify it. Very few people probably does. I will choose the simplest method...
-
CCoder,
Yes, pocrt.dll will do it's own initialization, so it's easier to use from assembly code.
Your understanding seems correct...