线程安全的xll函数

我有这个愚蠢的xll函数:

__declspec(dllexport) long F(long arg1, long arg2) { return arg1 + arg2; } 

我想这没有问题,最终的Excel函数将是线程安全的。

但是如何使用数组和返回数组呢? 考虑例如function:

 __declspec(dllexport) LPXLOPER12 WINAPI G(LPXLOPER12 arrayin1, LPXLOPER12 arrayin2) { static XLOPER12 xlArray; // the reference to this one is going to be returned // treating arrayin1 and arrayin2 and outputting something in xlArray return static_cast<LPXLOPER12>(&xlArray); } 

很明显static对于线程安全和并发调用是不利的。 我应该如何修改我的函数来确保线程安全?

编辑

使用手柄的代码示例:

 __declspec(dllexport) LPXLOPER12 WINAPI CreateComplex(LPXLOPER12 arrayin1, LPXLOPER12 arrayin2) { static XLOPER12 xlArray; xlArray.xltype = xltypeStr; if (arrayin1->xltype != xltypeNum) { xlArray.val.str = L"blah"; return static_cast<LPXLOPER12>(&xlArray); } if (arrayin2->xltype != xltypeNum) { xlArray.val.str = L"blahblah"; return static_cast<LPXLOPER12>(&xlArray); } double real = arrayin1->val.num; double imag = arrayin2->val.num; Complex * z = new Complex(real, imag); char * handle = StoreObject("Complex", z); xlArray.xltype = xltypeStr; FromCharPtrToWChartPtr(handle, &xlArray.val.str); return static_cast<LPXLOPER12>(&xlArray); } __declspec(dllexport) double WINAPI GetComplexNorm(LPXLOPER12 arrayin) { char *handle = nullptr; FromWChartPtrToWharPtr(arrayin->val.str, &handle); Complex * z = (Complex*)RetrieveObject(handle); double res = z->getNorm(); return res; } 

Complex是一个经典的复数类,“记忆”function如下(注意它是旧的C代码):

 #include "stdafx.h" #include <string.h> #include "memory.h" #include <stdio.h> #include "XLCALL.H" #include <cstdlib> void FromCharPtrToWChartPtr(char * from, XCHAR **to) { size_t len = strlen(from); *to = new XCHAR[len + 1]; *to[0] = static_cast<XCHAR>(len); if (len > 0) { mbstowcs(*to + 1, from, len + 1); } } void FromWChartPtrToWharPtr(XCHAR * from, char **to) { size_t len = from[0]; *to = new char[len + 1]; wcstombs(*to, from + 1, len); } typedef struct _TObject { char *name; int version; /* increments by 1 for every new store operation */ void *data; void *next; } TObject; static TObject *cache = NULL; #define SEPARATOR '#' TObject* FindNode(char* name) { TObject *node = cache; while (node) { if (_stricmp(node->name, name) == 0) break; node = (TObject*)node->next; } return node; } #define FAILURE -1 #define SUCCESS 0 char* StoreObject(char* name, void* data) { static char *routine = "StoreObject"; int status = FAILURE; char *handle = NULL; TObject *node; static char buffer[255]; if (data == NULL) { // error to handle later goto done; } if (name == NULL) { // error to handle later goto done; } if (strlen(name) > 200) { // error to handle later goto done; } node = FindNode(name); if (node == NULL) { node = new TObject(); if (node == NULL) goto done; node->name = _strdup(name); node->version = 1; node->data = data; node->next = cache; cache = node; } else { node->version += 1; delete node->data; // should I template taylor the object destruction diffenrently ? node->data = data; } sprintf(buffer, "%s%c%d\0", node->name, SEPARATOR, node->version); handle = _strdup(buffer); if (handle == NULL) goto done; strcpy(handle, buffer); status = SUCCESS; done: if (status != SUCCESS) { // error to handle later delete handle; handle = NULL; } return handle; } void* RetrieveObject(char* handle) { static char *routine = "RetrieveObject"; int status = FAILURE; void *data = NULL; char *name = NULL; TObject *node; char *sep; if (handle == NULL) { // error to handle later goto done; } name = _strdup(handle); if (name == NULL) goto done; /* remove version number from lookup string */ sep = strchr(name, SEPARATOR); if (sep != NULL) *sep = '\0'; node = FindNode(name); if (node == NULL) { // error to handle later goto done; } data = node->data; status = SUCCESS; done: if (status != SUCCESS) { // error to handle later data = NULL; } delete name; return data; } void FreeObjects() { TObject *next = cache; TObject *node; while (next) { node = next; next = (TObject*)node->next; delete node->name; delete node->data; delete node; } } 

在这个MSN网页上有一个很好的介绍,确实静态不是线程安全的,你需要将新的variables分配给线程本地安全内存。 你可以看看前面提到的页面中的函数get_thread_local_xloper12

Interesting Posts