首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ VB6接口问题

C++ VB6接口问题
EN

Stack Overflow用户
提问于 2010-04-03 00:09:58
回答 1查看 581关注 0票数 0

为了解决这个问题,我绞尽脑汁,任何见解都将不胜感激:

我有一个C++ exe,它从主线程中的一些硬件获取数据,并在另一个线程(线程2)中处理它。

我使用了一个c++动态链接库来提供一些从线程2调用的数据处理函数。

我需要在VB6中创建另一组数据处理函数。因此,我已经创建了一个VB6 dll,使用外接程序vbAdvance创建标准dll。

当我从主线程调用这个VB6动态链接库中的函数时,一切都完全按照预期工作。

当我在线程2中从这个VB6 dll调用函数时,我得到一个访问冲突。

我已经将错误跟踪到CopyMemory命令,似乎如果在来自主线程的调用中使用该命令,这是可以的,但在来自进程线程的调用中,它会导致异常。为何会这样呢?据我所知,线程共享相同的地址空间。

下面是我的VB dll中的代码

代码语言:javascript
复制
Public Sub UserFunInterface(ByVal in1ptr As Long, ByVal out1ptr As Long, ByRef nsamples As Long)
Dim myarray1() As Single
Dim myarray2() As Single
Dim i As Integer
ReDim myarray1(0 To nsamples - 1) As Single
ReDim myarray2(0 To nsamples - 1) As Single


With tsa1din(0)  ' defined as safearray1d in a global definitions module
    .cDims = 1
    .cbElements = 4
    .cElements = nsamples
    .pvData = in1ptr
End With

With tsa1dout
    .cDims = 1
    .cbElements = 4
    .cElements = nsamples
    .pvData = out1ptr
End With
CopyMemory ByVal VarPtrArray(myarray1), VarPtr(tsa1din(0)), 4
CopyMemory ByVal VarPtrArray(myarray2), VarPtr(tsa1dout), 4

For i = 0 To nsamples - 1
    myarray2(i) = myarray1(i) * 2
Next i
ZeroMemory ByVal VarPtrArray(myarray1), 4
ZeroMemory ByVal VarPtrArray(myarray2), 4


End Sub

更新:-

谢谢你的评论,实际上我已经找到了一个可以做我需要它做的工作。我已经将数组的所有指针操作放在VB中的一个单独函数中,在设置例程期间,我从C++应用程序的主线程调用此函数。然后,处理线程调用dll中的另一个例程,该例程只包含要对数组数据执行的计算(不包含CopyMemory命令)。这似乎是可行的。

EN

回答 1

Stack Overflow用户

发布于 2010-04-03 00:45:47

在调用VB6 DLL导出之前,必须在第二个线程初始化VB6运行时时初始化COM。因此,首先在工作线程上调用CoInitilize,然后从VB6 ActiveX DLL创建一个虚拟对象(abd立即释放它),然后调用函数。

您可以在导出中完成这两个步骤,但这要复杂得多。你不能调用VB内部函数,也不能声明API函数,只能调用类型库导入的函数。我的线程入口函数是这样开始的:

代码语言:javascript
复制
'--- initialize COM libs
Call CoInitialize(0)
'--- create a VB6 object
Call CoCreateInstance(CLSIDFromProgID(PROGID_DUMMY), Nothing, CLSCTX_INPROC_SERVER, VBGUIDFromString(STR_IID_IUnknown), Nothing)
On Error GoTo ...

其中所有API函数都来自线程类型库。下面是一个函数,可以告诉您VB运行时是否在当前线程上

代码语言:javascript
复制
Private Function pvIsVbRuntime() As Boolean
    Dim lIdx            As Long

    lIdx = GetModuleHandle("MSVBVM60.DLL")
    lIdx = GetProcAddress(lIdx, "__vbaSetSystemError")
    Call RtlMoveMemory(lIdx, ByVal lIdx + 9, 4)
    Call RtlMoveMemory(lIdx, ByVal lIdx, 4)
    If TlsGetValue(lIdx) <> 0 Then
        pvIsVbRuntime = True
    End If
End Function

所有API函数也都是从类型库导入的。它很麻烦,我只在SP6上测试过。

无论如何,我认为你的这类问题应该在vbAdvance插件中得到很好的记录。你最好在C++代码中“准备”工作线程。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2567701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档