从 C# 调用托管 C++ 中的向量
Call a vector in managed C++ from C#
我想要一个包含多个独立变量的向量。在我的 C++ header(.h) 中,我这样定义它:
private:
// Static data structure holding independent variables
static vector<double>* indVariables;
在我的 .cpp 文件中,它的定义相同,然后我将不得不在其他一些函数中使用这个向量,如下所示:
static vector<double>* indVariables;
void fun(int m, int n)
{
for (i = 0; i < m; ++i)
{
ai = indVariables[i];
temp = exp(-n * (ai - 8.0));
}
} /* fun */
现在在 C# 中,我想将一组数字复制到此向量并将其调回 C++,如下所示:
var matu = new double[]{ 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.indVariables = matu;
我该怎么做?
第一个问题是因为它是私有的,所以我在 C# 中看不到它。我必须做到 public 还是有其他方法?然后如何为这个向量赋值?
引用 C++/CX 的 Collections 文档:
In a Visual C++ component extensions (C++/CX) program, you can make
free use of Standard Template Library (STL) containers, or any other
user-defined collection type. However, when you pass collections back
and forth across the Windows Runtime application binary interface
(ABI)—for example, to a XAML control or to a JavaScript client—you
must use Windows Runtime collection types.
因此,您可以在内部尽可能多地使用 STL 容器,但您将无法在运行时组件之间传递它们,因为它们不跨越 ABI 边界。
快速解决方法是通过 <collection.h>
.
使用 Platform::Collections
命名空间中可用的 Vector
class
将您的 header 声明更改为:
public:
static Vector<Double>^ IndVariables;
您的 C# 组件也需要更改:
var matu = new Double[] { 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.IndVariables = matu;
这是未经测试的代码,因此上面的代码片段中应该存在语法错误或其他小问题。
它是私有的这一事实确实存在一个问题,但我认为将其设为 public 不仅可以解决您的问题。正如理查德所说,C# 不知道 std::vector 是什么。我不太了解你的代码结构,它在做什么,它是如何使用的等等,但是,如果你只需要为向量分配一个 list/array 数字,你可以使用一个列表<> 在您的 C# 代码中,并在您的 CLI project/file:
中将向量的赋值包装在类似这样的内容中
void Assign(Collections::Generic::List<double>^ l )
{
IndVariables->clear();
for each (double i in l)
{
IndVariables->push_back(i);
}
}
然后在您的 C# 程序中,您将编写(或者您已经声明了您的 List<>):
yourCppClass.Assign(new List<double>(){0.0, 42.0, 8.0});
您还可以添加额外的包装方法来操作或访问矢量。同样,这可能适合也可能不适合,具体取决于您的代码结构。
我想要一个包含多个独立变量的向量。在我的 C++ header(.h) 中,我这样定义它:
private:
// Static data structure holding independent variables
static vector<double>* indVariables;
在我的 .cpp 文件中,它的定义相同,然后我将不得不在其他一些函数中使用这个向量,如下所示:
static vector<double>* indVariables;
void fun(int m, int n)
{
for (i = 0; i < m; ++i)
{
ai = indVariables[i];
temp = exp(-n * (ai - 8.0));
}
} /* fun */
现在在 C# 中,我想将一组数字复制到此向量并将其调回 C++,如下所示:
var matu = new double[]{ 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.indVariables = matu;
我该怎么做?
第一个问题是因为它是私有的,所以我在 C# 中看不到它。我必须做到 public 还是有其他方法?然后如何为这个向量赋值?
引用 C++/CX 的 Collections 文档:
In a Visual C++ component extensions (C++/CX) program, you can make free use of Standard Template Library (STL) containers, or any other user-defined collection type. However, when you pass collections back and forth across the Windows Runtime application binary interface (ABI)—for example, to a XAML control or to a JavaScript client—you must use Windows Runtime collection types.
因此,您可以在内部尽可能多地使用 STL 容器,但您将无法在运行时组件之间传递它们,因为它们不跨越 ABI 边界。
快速解决方法是通过 <collection.h>
.
Platform::Collections
命名空间中可用的 Vector
class
将您的 header 声明更改为:
public:
static Vector<Double>^ IndVariables;
您的 C# 组件也需要更改:
var matu = new Double[] { 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.IndVariables = matu;
这是未经测试的代码,因此上面的代码片段中应该存在语法错误或其他小问题。
它是私有的这一事实确实存在一个问题,但我认为将其设为 public 不仅可以解决您的问题。正如理查德所说,C# 不知道 std::vector 是什么。我不太了解你的代码结构,它在做什么,它是如何使用的等等,但是,如果你只需要为向量分配一个 list/array 数字,你可以使用一个列表<> 在您的 C# 代码中,并在您的 CLI project/file:
中将向量的赋值包装在类似这样的内容中void Assign(Collections::Generic::List<double>^ l )
{
IndVariables->clear();
for each (double i in l)
{
IndVariables->push_back(i);
}
}
然后在您的 C# 程序中,您将编写(或者您已经声明了您的 List<>):
yourCppClass.Assign(new List<double>(){0.0, 42.0, 8.0});
您还可以添加额外的包装方法来操作或访问矢量。同样,这可能适合也可能不适合,具体取决于您的代码结构。