- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I get an access violation on return from CreateThread.
The call to create the thread is made under WM_CREATE in a standard Windows application, and in the thread I run a DLL that checks a licence key in the registry. If there's an error it issues a message, but otherwise - normally - it takes no action. The DLL requires no arguments so I create the thread with 0 as the lpParameter (4th argument) ...
handles(1) = CreateThread(NULL,0,loc(ExecRtnl),0,0,loc(idThread))
The relevant code for ExecRtnl is:
integer*4 hlic,iret
pointer (licaddr,rtn_checklicence)
...
!Get handle of the licence dll
hlic = loadlibrary("Licence.dll"C)
if(hlic==0)call prgerr(0,'Error locating Licence.dll','aFMIS/ExecRtnl','X')
!Get address of the licence function
licaddr = getprocaddress(hlic,"CHECKLICENCE"C)
if(licaddr==0)call prgerr(0,'Error locating routine licence in Licence.dll.','aFMIS/ExecRtnl','X')
!Check licence against that encrypted in the registry.
call rtn_checklicence
iret = freelibrary(hlic)
ExecRtnl = 1
The DLL works well, but on return to the main program, after all other jobs under WM_CREATE have been completed, I get an access violation. I have found 3 ways around this:
1: Pass a dummy argument from the call to CreateThread all the way through to the DLL.
2: Disable an internal read (string to integer) in the DLL.
3: Disable the call to FreeLibrary on return of the DLL.
Any of the above actions removes the access violation, and the first and third ones enable the program to proceed normally.
I have used this general technique for creating threads and running DLLs many times before without problems, but this is the first time I have used a DLL the requires no arguments. I have spent many hours reading through websites and studying examples written in C and cannot see where I am going wrong.
Does anyone have any suggestions?
With many thanks in advance
Mike
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I remember that there is some problem with createThread api function I use
BeginThreadEx(null_security_attributes,0,LOC(StartThreadFunc),0,0,LOC(iThreadID))
instead and there are no problems (it was mentioned somewhere long ago).
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you mean that it literally has no arguments? You must not do that. When you utilize any sort of callback technique, the called procedure must have fixed interface. Compare e.g. DlgSetSub, where the called routine must have prototype SUBROUTINE(Dlg, id, iEvent).
The error gets exposed when the target routine is STDCALL: there, the callee cleans the stack. In your case, the caller (CreateThread) pushes there one, but the called routine on exit pops none, creating a mismatch (likely resulting in a wrong return address or who knows). With C (__cdecl) (Ifort default), you could get away with that.
So, in a nutshell, your thread function must be a STDCALL function with exactly 1 argument, which you need not necessarily use. If you cannot change the prototype, write a wrapper function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for replies.
In my original post I was perhaps not quite as clear as I would have liked - I had already tried passing dummy arguments into and out of the DLL in the created thread, but still had problems.
I have solved the problem by including a call to ExitThread in the DLL - something I have not done before in many other DLLs. I quote from the online documentation:
"ExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, in C++ code, you should return from your thread function."
I assumed, since all my other threads simply returned successfully, that the C++ method was the way to go. I would love to hear some comments and some theory on this point.
With many thanks in advance,
Mike

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page