如果锁定不安全,如何使SAFEARRAYs线程安全?

时间:2017-05-28 05:26:59

标签: c++ vb.net multithreading vba safearray

我正在编写一个C ++ DLL,它从Excel VBA传入SAFEARRAY。 DLL有多个线程共享SAFEARRAY(读取和写入它们)。在试图找出如何安全地进行共享时,我遇到了this bit of MSDN documentation

  

例如,考虑使用SafeArrayLock和SafeArrayUnlock函数的应用程序。如果从同一SAFEARRAY数据类型实例上的不同线程同时调用这些函数,则可能会创建不一致的锁定计数。这最终将导致SafeArrayUnlock函数返回E_UNEXPECTED。您可以通过提供自己的同步代码来防止这种情况。

令我困惑的是因为我认为锁的全部意义在于确保线程的安全性,并且显然这种锁定功能并不适用于此。但是为什么需要锁定单线程应用程序呢?

SafeArrayLock的文档还说该函数“在数组描述符的pvData中放置一个指向数组数据的指针”,但是通过我的测试,即使从未调用过SafeArrayLock,pvData指针仍然有效(并且锁定计数是0)。例如,这个函数:

void __declspec(dllexport) __stdcall testfun(VARIANT& vararr) {
    if (vararr.parray->cLocks != 0) throw -1; 
    else {
        double* data = (double*) vararr.parray->pvData;
        data[5] = 4.1;
    }
}

有效地写入存储在vararr中的数组,并且在调用它的VBA中可以看到更改。怎么了?

鉴于pvData和不安全的锁定机制看似持久,我的本能就是废弃所有数组操作函数,让我的线程随心所欲地进入pvData(写入永远不会发生碰撞,所以可能会出错?)但是由于原因不明,其他人在此谨慎对抗手动阵列操作。什么是正确的方法?提前谢谢。

0 个答案:

没有答案