简体   繁体   English

如何在C ++中创建和初始化双精度SAFEARRAY以传递给C#

[英]How to create and initialize SAFEARRAY of doubles in C++ to pass to C#

My C# method needs to be invoked from C++ 我需要从C ++调用我的C#方法

Originally my C# method takes a parameter of type double[], but when calling from C++ it becomes a SAFEARRAY 最初我的C#方法接受double []类型的参数,但是当从C ++调用时它变成了SAFEARRAY

In C++ I need to take data from an array of doubles, and populate a SAFEARRAY. 在C ++中,我需要从双精度数组中获取数据,并填充SAFEARRAY。 I have not found any sample code to do this. 我没有找到任何示例代码来执行此操作。

Any help is appreciated 任何帮助表示赞赏

Following is the code to create a safearray in C++. 以下是在C ++中创建safearray的代码。

#include<oaidl.h>

void CreateSafeArray(SAFEARRAY** saData)        
{
    double data[10]; // some sample data to write into the created safearray
    SAFEARRAYBOUND  Bound;
    Bound.lLbound   = 0;
    Bound.cElements = 10;

    *saData = SafeArrayCreate(VT_R8, 1, &Bound);

    double HUGEP *pdFreq;
    HRESULT hr = SafeArrayAccessData(*saData, (void HUGEP* FAR*)&pdFreq);
    if (SUCCEEDED(hr))
    {
            // copy sample values from data[] to this safearray
        for (DWORD i = 0; i < 10; i++)
        {
            *pdFreq++ = data[i];
        }
        SafeArrayUnaccessData(*saData);
    }
}

Free the pointer when you are finished like the following code- 完成时释放指针,如下面的代码 -

  SAFEARRAY* saData;
  CreateSafeArray(&saData); // Create the safe array
  // use the safearray
  ...
  ...

  // Call the SafeArrayDestroy to destroy the safearray 
  SafeArrayDestroy(saData);
  saData = NULL; // set the pointer to NULL

If you use ATL for C++, then better use CComSafeArray declared in "atlsafe.h". 如果你使用ATL for C ++,那么最好使用“atlsafe.h”中声明的CComSafeArray。 This is wrapper for SAFEARRAY. 这是SAFEARRAY的包装。 link text 链接文字

Continuing on @Liton's answer, I want to stress his last sentence, ie ATL's CComSafeArray . 继续@Liton的回答,我想强调他的最后一句话,即ATL的CComSafeArray It really can save you a lot of typing. 它真的可以节省你很多打字。 CComSafeArray has C++ constructors, destructors, operator overloads including one for [ ] that gives you an read / write reference to any element in the SAFEARRAY . CComSafeArray具有C ++构造函数,析构函数,运算符重载,包括[]的一个,它为您提供对SAFEARRAY任何元素的读/写引用。 In short, you can really focus on your business logic and needn't worry about the SAFEARRAY plumbing: 简而言之,您可以真正专注于您的业务逻辑,而无需担心SAFEARRAY管道:

#include <atlbase.h>
#include <atlsafe.h>
// ...

    CComSafeArray<double> arr(10);
    arr[0] = 2.0;
    arr[1] = 3.0;
    arr[2] = 5.0;
    // ...

At the very least, even if you're not going to use CComSafeArray it's worthwhile to deconstruct its source code in <atlsafe.h> giving you better insight on the what, when, why and how on SAFEARRAY functions. 至少,即使您不打算使用CComSafeArray也值得在<atlsafe.h>解构其源代码,让您更好地了解SAFEARRAY函数的内容,时间,原因和方式。

Passing SAFEARRAYs is not recommended. 不建议通过SAFEARRAY。 It is recommended to place the SAFEARRAY into a VARIANT. 建议将SAFEARRAY放入VARIANT。 Further, the SAFEARRAY should hold VARIANT data. 此外,SAFEARRAY应该保存VARIANT数据。 This gives the best of all worlds and makes passing VARIANT SAFEARRAY of VARIANTs more useful to other languages. 这提供了所有世界中最好的,并使VARIANT的VARIANT SAFEARRAY对其他语言更有用。 Eg C++ to VB / C# (Note it is up to the caller to free/destroy the SAFEARRAY) 例如C ++到VB / C#(注意由调用者来释放/销毁SAFEARRAY)

Building on the previous code 以前的代码为基础

// A VARIANT holding a SAFEARRAY of VARIANTs
VARIANT vRet;

SAFEARRAYBOUND Bound;
Bound.lLbound = 0;
Bound.cElements = 10;

SAFEARRAY * psaData = SafeArrayCreate(VT_VARIANT, 1, &Bound);

VARIANT HUGEP * pData = NULL;
HRESULT hr = SafeArrayAccessData(psaData, (void HUGEP * FAR *)&pData);
if (SUCCEEDED(hr))
{
    for (short i = 0; i < 10; ++i,++pData)
    {
        ::VariantInit(pData);
        pData->vt = VT_I2;
        pData->iVal = i;
    }

    SafeArrayUnaccessData(psaData);
}

vRet.vt = VT_ARRAY | VT_VARIANT;
vRet.parray = psaData;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM