how to init runtime of threadproc in activex dll without multiuse class creation-reg
Dear Trick,
can you clarify how to init runtime of Threadproc in actx dll set to apartment threaded where the thread is created using CreateThread api in the actx dll without using multiuse class of dll with CreateObject thru vbdllgetclassobject.The standard exe just loads the actx dll thru project references.
regards,
JSVenu
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Please attach the example which causes the error.
There is no reason to performing special initialization for an ActiveX-DLL because it's initialized automatically.
1 Attachment(s)
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Quote:
Originally Posted by
The trick
Please attach the example which causes the error.
There is no reason to performing special initialization for an ActiveX-DLL because it's initialized automatically.
Dear Trick,
I made a simple project which is attached.
The simple project consists of two projects in simpleproject folder which are
1. stdexe project Displayaformofdllinnewthreadfromactivexd in stdexe folder.
2. Actx dll project actxdllwithapt_threaded in actxdllaptthd folder.
Just compile actxdllwithapt_threaded actx project and generate actxdllwithapt_threaded.dll
Just include actxdllwithapt_threaded.dll in Displayaformofdllinnewthreadfromactivexd std exe project from project references in the IDE and compile to Displayaformofdllinnewthreadfromactivexd.exe.
Now when we run Displayaformofdllinnewthreadfromactivexd.exe in compiled mode outside IDE it displays form of
actx dll in new thread whenever we click on DisplayFormofAptThreadedactxDLL button of displayed form.
In the following code
Code:
Public Function ThreadProc( _
ByRef tData As tThreadData) As Long
Dim cObj As IUnknown
Dim tempobj As Class1
Dim frm As Form1
Set cObj = CreateIExprSrvObj(0, 4, 0)
CoInitialize ByVal 0&
Set tempobj = CreateObject("actxdllwithapt_threaded.Class1") 'init runtime
Set frm = New Form1
frm.Show vbModal
Set frm = Nothing
CoUninitialize
Set cObj = Nothing
Set tempobj = Nothing
End Function
I am initializing runtime of ThreadProc use the following code:
Set tempobj = CreateObject("actxdllwithapt_threaded.Class1") 'init runtime
I donot want to use Class1 multiuse class for initializing runtime for this ThreadProc.
Instead of the above line containing CreateObject using multiuse class class1 I want to use vbdllgetclassobject for initializing
this actx dll ThreadProc for displaying the dll form in this ThreadProc in Apartment threaded mode since CreateObject internally calls vbdllgetclassobject in the cycle.
I can solve the above example using vbdllgetclassobject by setting actx dll to single threaded.But I wanted to solve it using vbdllgetclassobject by setting actx dll to apt threaded since it is supposed to work since CreateObject internally calls vbdllgetclassobject. But it is not working in apt mode using vbdllgetclassobject explicitly.
You can see that the ThreadProc in actx dll will not initialize automatically as you said.
This is the sincere explanation with simple example I can give you Trick without any intention of hijacking any threads.
regards,
JSVenu
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Code:
Public Function ThreadProc( _
ByVal lUnused As Long) As Long
Dim cExprSrv As IUnknown
Dim cInitObj As IUnknown
Dim cForm As Form1
Set cExprSrv = CreateIExprSrvObj(0, 4, 0)
CoInitialize ByVal 0&
Set cInitObj = InitVbProjContext()
Set cForm = New Form1
cForm.Show vbModal
Set cForm = Nothing
Set cInitObj = Nothing
CoUninitialize
End Function
Public Function InitVbProjContext() As IUnknown
Dim pVBHeader As Long
Dim pCOMData As Long
Dim lOfstRegInfo As Long
Dim pRegInfo As Long
Dim pfn As Long
Dim hLib As Long
Dim iTypes(2) As Integer
Dim vParams(2) As Variant
Dim lList(2) As Long
Dim bIID(1) As Currency
Dim cFactory As IUnknown
Dim cObject As IUnknown
Dim hr As Long
Dim vRet As Variant
hLib = GetModuleHandle(StrPtr("actxdllwithapt_threaded.dll"))
pfn = GetProcAddress(hLib, "DllGetClassObject")
If pfn = 0 Then Exit Function
' // Get VBHeader
GetMem4 ByVal pfn + 2, pVBHeader
' // Get COM data
GetMem4 ByVal pVBHeader + &H54, pCOMData
' // Get Reg info
GetMem4 ByVal pCOMData, lOfstRegInfo
pRegInfo = pCOMData + lOfstRegInfo
' // IClassFactory
bIID(0) = 0.0001@
bIID(1) = 504403158265495.5712@
hr = DllGetClassObject(ByVal pRegInfo + &H14, bIID(0), cFactory)
If hr >= 0 And Not cFactory Is Nothing Then
' // Call IClassFactory::CreateInstance
iTypes(0) = vbLong
iTypes(1) = vbLong
iTypes(2) = vbLong
bIID(0) = 0
vParams(0) = 0&
vParams(1) = VarPtr(bIID(0))
vParams(2) = VarPtr(cObject)
lList(0) = VarPtr(vParams(0))
lList(1) = VarPtr(vParams(1))
lList(2) = VarPtr(vParams(2))
hr = DispCallFunc(ByVal ObjPtr(cFactory), &HC, CC_STDCALL, vbLong, 3, iTypes(0), lList(0), vRet)
If hr >= 0 And vRet >= 0 Then
Set InitVbProjContext = cObject
End If
End If
End Function
You don't need this code so you already use the registry-dependent code when you create an instance in the EXE.
1 Attachment(s)
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Quote:
Originally Posted by
The trick
Code:
Public Function ThreadProc( _
ByVal lUnused As Long) As Long
Dim cExprSrv As IUnknown
Dim cInitObj As IUnknown
Dim cForm As Form1
Set cExprSrv = CreateIExprSrvObj(0, 4, 0)
CoInitialize ByVal 0&
Set cInitObj = InitVbProjContext()
Set cForm = New Form1
cForm.Show vbModal
Set cForm = Nothing
Set cInitObj = Nothing
CoUninitialize
End Function
Public Function InitVbProjContext() As IUnknown
Dim pVBHeader As Long
Dim pCOMData As Long
Dim lOfstRegInfo As Long
Dim pRegInfo As Long
Dim pfn As Long
Dim hLib As Long
Dim iTypes(2) As Integer
Dim vParams(2) As Variant
Dim lList(2) As Long
Dim bIID(1) As Currency
Dim cFactory As IUnknown
Dim cObject As IUnknown
Dim hr As Long
Dim vRet As Variant
hLib = GetModuleHandle(StrPtr("actxdllwithapt_threaded.dll"))
pfn = GetProcAddress(hLib, "DllGetClassObject")
If pfn = 0 Then Exit Function
' // Get VBHeader
GetMem4 ByVal pfn + 2, pVBHeader
' // Get COM data
GetMem4 ByVal pVBHeader + &H54, pCOMData
' // Get Reg info
GetMem4 ByVal pCOMData, lOfstRegInfo
pRegInfo = pCOMData + lOfstRegInfo
' // IClassFactory
bIID(0) = 0.0001@
bIID(1) = 504403158265495.5712@
hr = DllGetClassObject(ByVal pRegInfo + &H14, bIID(0), cFactory)
If hr >= 0 And Not cFactory Is Nothing Then
' // Call IClassFactory::CreateInstance
iTypes(0) = vbLong
iTypes(1) = vbLong
iTypes(2) = vbLong
bIID(0) = 0
vParams(0) = 0&
vParams(1) = VarPtr(bIID(0))
vParams(2) = VarPtr(cObject)
lList(0) = VarPtr(vParams(0))
lList(1) = VarPtr(vParams(1))
lList(2) = VarPtr(vParams(2))
hr = DispCallFunc(ByVal ObjPtr(cFactory), &HC, CC_STDCALL, vbLong, 3, iTypes(0), lList(0), vRet)
If hr >= 0 And vRet >= 0 Then
Set InitVbProjContext = cObject
End If
End If
End Function
You don't need this code so you already use the registry-dependent code when you create an instance in the EXE.
Dear Trick,
Thankyou for the reply.
I modified the activex dll (activex dll project code attached) according to above code but when I run the standard exe by including the dll thru project settings it crashes.Please clarify.
regards,
JSVenu
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Quote:
Code:
Public Declare Function DllGetClassObject Lib "actxdllwithapt_threaded.DLL" ( _
ByRef pClsid As Any, _
ByRef pIID As Any, _
ByRef pObject As Any) As Long
Update the library name according the dll name.
1 Attachment(s)
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Quote:
Originally Posted by
The trick
Update the library name according the dll name.
Dear Trick,
Now it works fine.
But now the real problem came when I use vbdllgetclassobject .
When I use it it crashes in Createvbheadercopy.
I am attaching activex dll updated.It was my real problem.
regards,
JSVenu
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
You shouldn't use such approach. You shouldn't create a VBHeader copy.
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Quote:
Originally Posted by
The trick
You shouldn't use such approach. You shouldn't create a VBHeader copy.
Dear Trick,
It we use same vbheader then how to make sure that global variables are not cleared without using CreateVBHeaderCopy.
Same is my problem in ExeFormCreator project which I asked in the link
http://www.vbforums.com/showthread.p...multithreading #25.
Please clarify.
regards,
JSVenu
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
I already gave the code to make a NativeDLL from StdEXE.
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Quote:
Originally Posted by
The trick
Dear Trick,
Still I did not understand why CreateVBHeaderCopy fails in apartment threaded activex dll but works
1. in a standard exe even when the main thread vbheader is changed to apartment model.
2. in a activex dll set to single threaded model.
Has this something to do with global variables .Please clarify.
regards,
JSVenu
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
There are dozen of threads dealing with Multi Threading in VB6, all with a lot of complete code samples by The Trick and Schmidt.
Which also causes a lot of friction between them, because it seems they both have a strongly developed different opinion how thing should work.
But in all these threads you always need something different, which somehow is not dealt with in the given samples.
It seems you need something so special that:
a. it can not be done in VB6
b. it's only a hypothetical use case
c. you are trolling
d. all of the above
So what kind of application are you creating, because keep saying "just to study" is not a legitimate answer anymore
Please clarify!
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Dear Arnoutdv,
First let me thankyou for treating me asking something different but they are related to COM threading in a vc++ 6.0 unmanaged way. Actually I always think of COM threading to be understood in the same way as win32 unmanaged programming since I think in win32 way of unmanaged programming in vc++ 6.0.Now anyway I work in .NET where programming is made very easy.Long back when I worked in vb6.0 I maximum took support of vc++ 6.0 for advanced features like threading not available in vb6 at that time.I can tell you this type of interest makes me think and do some examples and ask the members since I really enjoy the subject from the solid examples provided by solid people.May be my thinking and doing like this help me in whatever language and platform I work in future in right direction.I am not developing any product and do not want to be idle.
This is the sincere explanation I can give you.
regards,
JSVenu
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
You shouldn't use the Apartment threading if you want to use shared memory because the compiler makes the apartment-aware code. Why do you need to use the Apartment threading mode if you want to use the shared variables? It exists exactly to isolate the global variables. You can't use shared variables in projects excluding the StdEXE one. (I don't consider the hacks like interception __vbaAptOffset etc.) Therefore it doesn't work in your cases.
Moreover you shouldn't use an ActiveX-DLL in such scenario (sharing variables) because you can't ensure the context initialization control even if you use the single-threaded option. Imagine you create an object from such AxDLL - it uses the initial project context:
https://i.ibb.co/CV5mjHg/vbhdr-1.jpg
, so all your global/static variables will be cleared when this object is being released:
https://i.ibb.co/W0YKggg/vbhdr-2.jpg
So you need to use the modified copy of the project-vb-header which contains exactly 0 such variables. The project i sent earlier (NativeDLL) does exactly that but you should control the lifetime of all the variables like in C/C++. All the variables are shared like in such languages.
So if you want coding in more low-level you should be more responsible.
Re: how to init runtime of threadproc in activex dll without multiuse class creation-
Quote:
Originally Posted by
The trick
You shouldn't use the Apartment threading if you want to use shared memory because the compiler makes the apartment-aware code. Why do you need to use the Apartment threading mode if you want to use the shared variables? It exists exactly to isolate the global variables. You can't use shared variables in projects excluding the StdEXE one. (I don't consider the hacks like interception __vbaAptOffset etc.) Therefore it doesn't work in your cases.
Moreover you shouldn't use an ActiveX-DLL in such scenario (sharing variables) because you can't ensure the context initialization control even if you use the single-threaded option. Imagine you create an object from such AxDLL - it uses the initial project context:
http://www.vbforums.com/images/ieimages/2020/03/1.jpg
, so all your global/static variables will be cleared when this object is being released:
http://www.vbforums.com/images/ieimages/2020/03/1.jpg
So you need to use the modified copy of the project-vb-header which contains exactly 0 such variables. The project i sent earlier (NativeDLL) does exactly that but you should control the lifetime of all the variables like in C/C++. All the variables are shared like in such languages.
So if you want coding in more low-level you should be more responsible.
Dear Trick,
Thankyou very much for your awesome support and solid explanation which I understood upto some extent and will try to understand well and I am grateful to you for the help extended.
regards,
JSVenu