提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!

原文由本人于2007年8月1日 18:52:59 发布于wyev.com(该域名已停用)。

不使用新线程回调成功,但使用新的线程回调VB出现<程序遇到问题需要关闭...>的错误。我为这个问题已经头疼几天了,问了微软的工程师,答复如下:

In vb6,Calling a function back from a different thread will cause access violations, so, Please prevent such designs.

看来还是要另想办法啦^_^。

---源代码如下--- MyTest.Dll (编译环境:VS2005) MyTest.c

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <windows.h>
typedef void (__stdcall *FUNPTR)(BSTR pbstr);
typedef struct _TEST_PARA{
	long pfunA;
	long pfunB;
}UTESTMY;

DWORD __stdcall NewRun(UTESTMY *pAt){
	FUNPTR vbFunA,vbFunB;
	vbFunA=(FUNPTR)(pAt->pfunA);
	vbFunB=(FUNPTR)(pAt->pfunB);
	vbFunA(SysAllocString(L""回调A""));
	vbFunB(SysAllocString(L""回调B""));
	free(pAt);
	return 0;
}
//线程结构体传参数回调VB显示程序遇到问题需要关闭
void __stdcall TheRun(long pfunA,long pfunB){
	HANDLE hThread;
	DWORD dwThreadId;
	UTESTMY *pAt;
	pAt=(UTESTMY *)malloc(sizeof(UTESTMY));
	pAt->pfunA=pfunA;
	pAt->pfunB=pfunB;
	hThread = 
CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)NewRun,pAt,0,&dwThreadId);
	WaitForSingleObject(hThread,INFINITE); 
	CloseHandle(hThread);
}

//下面这个在VB里调用是正常的
DWORD __stdcall ComRun(long pfunA,long pfunB){
	FUNPTR vbFunA,vbFunB;
	vbFunA=(FUNPTR)(pfunA);
	vbFunB=(FUNPTR)(pfunB);
	vbFunA(SysAllocString(L""回调A""));
	vbFunB(SysAllocString(L""回调B""));
	return 0;
}

MyTest.def

LIBRARY MyTest
      DESCRIPTION 'Library'
      EXPORTS
	  TheRun
	  ComRun

VB Code(编译环境:Visual Basic 6)

Form1.frm

Private Declare Sub TheRun Lib "MyTest.dll" (ByVal pfunA As Long, ByVal 
pfunB As Long)
Private Declare Function ComRun Lib "MyTest.dll" (ByVal pfunA As Long, ByVal 
pfunB As Long) As Integer

Private Sub Form_Load()
Call TheRun(AddressOf TestA, AddressOf TestB) '采用新线程回调出现问题
Call ComRun(AddressOf TestA, AddressOf TestB) '这个正常
End Sub
----------------
Module1.bas

Public Sub TestA(ByVal mystr As String)
MsgBox mystr
End Sub

Public Sub TestB(ByVal mystr As String)
MsgBox mystr
End Sub