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

发布于 2024-09-20 00:04:18 字数 171 浏览 15 评论 0原文

我的 C# 方法需要从 C++ 调用

最初我的 C# 方法采用 double[] 类型的参数,但是当从 C++ 调用时,它变成了 SAFEARRAY

在 C++ 中,我需要从双精度数组中获取数据,并填充 SAFEARRAY。我还没有找到任何示例代码来执行此操作。

任何帮助表示赞赏

My C# method needs to be invoked from C++

Originally my C# method takes a parameter of type double[], but when calling from C++ it becomes a SAFEARRAY

In C++ I need to take data from an array of doubles, and populate a SAFEARRAY. I have not found any sample code to do this.

Any help is appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

格子衫的從容 2024-09-27 00:04:18

以下是在 C++ 中创建安全数组的代码。

#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);
    }
}

完成后释放指针,如以下代码 -

  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

如果您使用 C++ 的 ATL,则最好使用“atlsafe.h”中声明的 CComSafeArray。这是 SAFEARRAY 的包装。 CComSafeArray 类

Following is the code to create a safearray in C++.

#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". This is wrapper for SAFEARRAY. CComSafeArray Class

我不咬妳我踢妳 2024-09-27 00:04:18

继续@Liton的回答,我想强调他的最后一句话,即ATL的CComSafeArray。它确实可以节省您大量的打字时间。 CComSafeArray 具有 C++ 构造函数、析构函数、运算符重载,其中包括一个 [ ] 运算符重载,它为您提供对 SAFEARRAY 中任何元素的读/写引用。简而言之,您可以真正专注于业务逻辑,而不必担心 SAFEARRAY 管道:

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

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

至少,即使您不打算使用 CComSafeArray值得在 中解构其源代码,让您更好地了解 SAFEARRAY 函数的内容、时间、原因和方式。

Continuing on @Liton's answer, I want to stress his last sentence, i.e. ATL's 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. In short, you can really focus on your business logic and needn't worry about the SAFEARRAY plumbing:

#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.

苍暮颜 2024-09-27 00:04:18

不建议传递 SAFEARRAY。建议将 SAFEARRAY 放入 VARIANT 中。此外,SAFEARRAY 应保存 VARIANT 数据。这提供了所有世界中最好的,并且使得传递 VARIANT 的 VARIANT SAFEARRAY 对其他语言更有用。例如,C++ 到 VB / C#(请注意,由调用者决定释放/销毁 SAFEARRAY)

基于之前的代码构建

// 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;

Passing SAFEARRAYs is not recommended. It is recommended to place the SAFEARRAY into a VARIANT. Further, the SAFEARRAY should hold VARIANT data. This gives the best of all worlds and makes passing VARIANT SAFEARRAY of VARIANTs more useful to other languages. E.g. C++ to VB / C# (Note it is up to the caller to free/destroy the 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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文