vb通过com使用多线程,真的多线程

wy24789 2015-05-11 10:01:51
vb使用CreateThread使用多线程时,很容易出错,找规律好像是创建的线程执行工程内代码时引起的,为了避免这种状况的出现,把线程代码都放在com内运行,再用vc写个dll创建线程,在里面调用这个com。这是真的多线程,不像用ActiveX exe,那是多进程
下面是exe文件代码,简单示例,工作正常,其它应用情况不明,欢迎测试、指教这个方法的可行性和稳定性

Private Declare Function CreateThread Lib "Kernel32.dll" (ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Private Declare Function TerminateThread Lib "Kernel32.dll" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Private Declare Function CloseHandle Lib "Kernel32.dll" (ByVal hObject As Long) As Long

Dim hThread1 As Long
Dim idThread1 As Long
Dim hThread2 As Long
Dim idThread2 As Long

Dim td1 As vbThreadData
Dim td2 As vbThreadData

Private Sub Form_Load()
td1.ProgId = "aatest1.Class1"
td1.param1 = 1
hThread1 = vbCreateThread(td1, idThread1)

td2.ProgId = "aatest1.Class1"
td2.param1 = 2
hThread2 = vbCreateThread(td2, idThread2)

MsgBox "线程1:" & hThread1 & " " & idThread1 & vbCrLf & "线程2:" & hThread2 & " " & idThread2
End Sub

Private Sub Form_Unload(Cancel As Integer)
TerminateThread hThread1, 0
CloseHandle hThread1
End Sub

Private Sub Timer1_Timer()
Text1.Text = td1.ProgId
Text2.Text = td1.param1
Text3.Text = td2.ProgId
Text4.Text = td2.param1
Text5.Text = td2.param1 - td1.param1
End Sub


com代码

Option Explicit

Implements IThread

Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)

Private Function IThread_Start(threadData As TLb_IvbThread.vbThreadData) As Long
Dim i As Long
MsgBox "IThread_Start: " & threadData.ProgId & " " & threadData.param1
For i = 0 To 1000000
threadData.param1 = i
threadData.ProgId = Now
Sleep 1
Next
End Function


dll代码


DWORD WINAPI ThreadStartRoutine(LPVOID lpThreadParameter)
{
HRESULT hr;
long exitCode=0;
CComPtr<IDispatch> clsptr;

vbThreadData *threadData=(vbThreadData *)lpThreadParameter;
hr=CoInitialize(0);
hr=clsptr.CoCreateInstance(threadData->progId);
if (SUCCEEDED(hr))
{
IThread *pIThread=0;
hr=clsptr->QueryInterface(&pIThread);
if (SUCCEEDED(hr))
{
hr=pIThread->Start(threadData,&exitCode);
pIThread->Release();
}
else MessageBox(0,TEXT("没有实现 IThread 接口"),TEXT("vbThread"),MB_ICONERROR);
clsptr.Release();
}
else MessageBox(0,TEXT("无法创建实例,请检查 ProgId"),TEXT("vbThread"),MB_ICONERROR);
CoUninitialize();
return (DWORD)exitCode;
}

extern "C" HANDLE WINAPI vbCreateThread(LPVOID lpParameter,LPDWORD lpThreadId)
{
return CreateThread(0,0,ThreadStartRoutine,lpParameter,0,lpThreadId);
}



工程下载地址http://download.csdn.net/detail/wy24789/8688357
...全文
501 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-05-19
  • 打赏
  • 举报
回复
COM Tutorial Samples Tutorial Home Using Samples First Lesson List of Lessons Click a lesson link below to jump to the tutorial narrative for the associated code sample. Directory/Sample Lesson Topic APPUTIL Lesson 0 Win32 Basics: Win32 Application Utility Library READTUT Lesson 1 Win32 Basics: Tutorial Reader and Linking to APPUTIL EXESKEL Lesson 2 Win32 Basics: Win32 EXE Skeleton Application DLLSKEL Lesson 3 Win32 Basics: Win32 DLL Skeleton DLLUSER Lesson 4 Win32 Basics: EXE User of a DLL COMOBJ Lesson 5 COM Objects: Containment and Aggregation in a DLL COMUSER Lesson 6 COM Objects: Nested Aggregation in an EXE User REGISTER Lesson 7 COM Components: Component Object Registration DLLSERVE Lesson 8 COM Components: Component Object DLL Server DLLCLIEN Lesson 9 COM Components: Client Application of DLL Server LICSERVE Lesson 10 COM Components: DLL Licensed Server LICCLIEN Lesson 11 COM Components: Client Application of Licensed Server MARSHAL Lesson 12 COM Components: Custom Interface Standard Marshaling MARSHAL2 Lesson 13 COM Components: Marshaling DLL Self-Registration LOCSERVE Lesson 14 COM Components: Local Server LOCCLIEN Lesson 15 COM Components: Client Application of Local Server APTSERVE Lesson 16 COM Components: Local Server with Multiple Apartments APTCLIEN Lesson 17 COM Components: Client of Multiple Apartment Server REMCLIEN Lesson 18 COM Components: Distributed COM (DCOM) Remote Client FRESERVE Lesson 19 COM Components: Free-threaded Server FRECLIEN Lesson 20 COM Components: Client of Free-threaded Server CONSERVE Lesson 21 COM Components: Connectable Object Server CONCLIEN Lesson 22 COM Components: Client of Connectable Object Server STOSERVE Lesson 23 COM Components: Structured Storage Server STOCLIEN Lesson 24 COM Components: Client of Structured Storage Server PERSERVE Lesson 25 COM Components: IPersistStream Persistent Object Server PERTEXT Lesson 26 COM Components: IPersistStreamInit Persistent Object Server PERDRAW Lesson 27 COM Components: IPersistStorage Persistent Object Server PERCLIEN Lesson 28 COM Components: Client of Persistent Object Servers DCDMARSH Lesson 29 COM Components: Standard Marshaling for DCOM DCDSERVE Lesson 30 COM Components: DCOM Server Using Security DCOMDRAW Lesson 31 COM Components: DCOM Client Using Security INC -- Common include directory used by the code samples LIB -- Common library directory used by the code samples TUTSAMP -- Main branch directory with TUTORIAL.EXE, MAKEALL.BAT, etc. Throughout the sample sequence a clear differentiation is maintained between client and server, with a separate lesson sample for each. Usually, each client/server pair covers an area of COM technology. Here is an overview of the technologies covered by the lessons. Basic Win32 application programming is covered in the APPUTIL, READTUT, EXESKEL, DLLSKEL, and DLLUSER lessons. APPUTIL provides a utility framework for building Win32 applications. It also contains some tools needed for tutorial purposes. READTUT is a very simple EXE application that shows how to link to the APPUTIL static library and call utility functions in it. READTUT also shows how to invoke the COM tutorial Web page reader that is used throughout the sample series. EXESKEL shows a basic Win32 skeleton EXE application built using APPUTIL. DLLSKEL and DLLUSER simularly show a basic Win32 DLL (Dynamic Link Library) skeleton and how to access it from an EXE user application. Basic COM object construction, custom interfaces, and techniques for coding their reuse using aggregation and containment are covered in COMOBJ and COMUSER. The implementation and use of the standard IUnknown interface is covered. The implementation and use of the custom ICar, IUtility, and ICruise interfaces is covered. Basic COM component construction, class factories, component object registration, and techniques for housing COM objects in COM component servers are covered in REGISTER, DLLSERVE, and DLLCLIEN. The implementation and use of the standard IClassFactory interface is covered. COM component Licensing is covered in LICSERVE and LICCLIEN. The implementation and use of the standard IClassFactory2 interface is covered. Out-of-Process local servers and the standard marshaling of custom interfaces are covered in MARSHAL, LOCSERVE, and LOCCLIEN. Explicit self-registration in the standard marshaling DLL is covered in MARSHAL2. The use of the MIDL language to specify custom interfaces is covered. The use of the MIDL compiler to produce proxy/stub marshaling servers is also covered. Apartment model server and client construction are covered in APTSERVE and APTCLIEN. Construction of multiple single-threaded apartments (STAs) in the same process is covered. DCOM (Distributed COM) with custom interfaces operating between client and server across machine boundaries is covered in REMCLIEN. Specifying the remote machine name in the COSERVERINFO structure is covered. Detailed DCOM security issues are not covered. Free-threaded COM components and their access by free-threaded clients are covered in FRESERVE and FRECLIEN. The use of several client worker threads in the multi-threaded apartment (MTA) is covered. The implementation and use of a custom IBall interface is covered. Connectable COM object technology is covered in CONSERVE and CONCLIEN. Event source and sink construction is covered. Implementation and use of the IConnectionPointContainer, IConnectionPoint, IEnumConnectionPoints, and IEnumConnections standard interfaces are covered. The implementation and use of the custom IBall and IBallSink interfaces is covered. Structured storage using COM's compound file technology is covered in STOSERVE and STOCLIEN. A COM-based scribble drawing application is used. Use of the IStorage and IStream standard interfaces is covered. The implementation and use of the custom IPaper and IPaperSink interfaces is covered. Persistent COM objects are covered in PERSERVE, PERTEXT, PERDRAW, and PERCLIEN. IPersistStream is covered in the PERSERVE components. IPersistStreamInit is covered in the PERTEXT components. IPersistStorage is covered in the PERDRAW components. The PERCLIEN client functions these various persistent objects and manages storage for all of them in various substorages and streams within one structured storage compound file. The implementation and use of the custom IPageList, ITextPage, IDrawPage, IPageListSink, ITextPageSink, and IDrawPageSink interfaces is covered. DCOM (Distributed COM) Security is covered in DCDMARSH, DCDSERVE, and DCOMDRAW. The use of CoInitializeSecurity is shown in the DCDSERVE and DCOMDRAW samples. Multiple clients accessing a shared single COM object across machine boundaries is shown in a simple network shared-drawing application. Process and activation security within NT network domains is discussed. Registry AppIDs and their LaunchPermission, AccessPermission, and RunAs named values are discussed. The use of the DCOMCNFG utility is covered. Back to page top © 1995-1998 Microsoft Corporation
PctGL 2015-05-16
  • 打赏
  • 举报
回复
引用 11 楼 wy24789 的回复:
[quote=引用 9 楼 PctGL 的回复:] 标准程序版的单元线程。。。
不懂,可否具体说说,“单元线程”这个怎么啦,好像《高级Visual Basic编程(Advanced Visual Basic)》那本书里有说到[/quote] 思路还是不错的,确实可以实现完全稳定,正常的多线程,但这个多线程之间是完完全全相互隔离的 就象两个进程一样的感觉,不同多进程的地方就是,总归是在同一个进程内,内存是可以随时简单易行的共享的 但代码就不行了,我没试,但我推测,如果线程2,使用主线程的对象 cls1,只要用了走不了几步就挂
wy24789 2015-05-16
  • 打赏
  • 举报
回复
不能访问主线程代码,只能简单数据类型,《高级Visual Basic编程(Advanced Visual Basic)》也有说到,好像是和内存分配有关,环境什么的
wy24789 2015-05-15
  • 打赏
  • 举报
回复
引用 9 楼 PctGL 的回复:
标准程序版的单元线程。。。
不懂,可否具体说说,“单元线程”这个怎么啦,好像《高级Visual Basic编程(Advanced Visual Basic)》那本书里有说到
PctGL 2015-05-14
  • 打赏
  • 举报
回复
标准程序版的单元线程。。。
bcrun 2015-05-14
  • 打赏
  • 举报
回复
我觉得楼主这个思路是可以的。
hpygzhx520 2015-05-13
  • 打赏
  • 举报
回复
抱歉,没仔细看,的确是没注册。
hpygzhx520 2015-05-13
  • 打赏
  • 举报
回复
如果不注册的话,例子工程是无法编译的
hpygzhx520 2015-05-12
  • 打赏
  • 举报
回复
报错,无法创建实例。
Tiger_Zhao 2015-05-12
  • 打赏
  • 举报
回复
《高级Visual Basic编程(Advanced Visual Basic)》
第十三章 VB中的线程
vansoft 2015-05-12
  • 打赏
  • 举报
回复
不明觉厉。 +10086
wy24789 2015-05-12
  • 打赏
  • 举报
回复
再次审视了下我的代码,实在是太简单了,才几行啊
wy24789 2015-05-12
  • 打赏
  • 举报
回复
引用 1 楼 Tiger_Zhao 的回复:
《高级Visual Basic编程(Advanced Visual Basic)》 第十三章 VB中的线程
这本书很好很强大,这么说这方法可行,没仔细看,他说得太深了,好长
引用 2 楼 hpygzhx520 的回复:
报错,无法创建实例。
是运行工程里面的例子吗,是不是没注册提供的com,如果是启动其它com请确保progId正确,对于vb一般是"工程名.类名"

1,066

社区成员

发帖
与我相关
我的任务
社区描述
VB 资源
社区管理员
  • 资源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧