我创建了一个由LabVIEW编译的.NET库,它具有一个带数字和被乘数的函数。此函数将返回一个数组,其中每个数字都与被乘数相乘。当在C#中调用该函数时,事实证明该函数采用非零索引数组(double[*]
)和int
作为参数,并返回另一个非零索引数组。
我可以用C#的Array.CreateInstance()
方法创建一个非零索引数组。但是我无法将此数组传递给函数,因为所需的数据类型是double[*]
。
从互联网上的研究来看,.NET似乎不支持非零索引数组类型。我试图找到一种方法来修改LabVIEW程序,以生成一个无法获得零索引数组的函数。
有关如何解决此问题的任何建议?
更新1
C#程序
const int Length = 5;
const int LowerBound = 1;
// Instanstiate a non-zero indexed array. The array is one-dimensional and
// has size specified by Length and lower bound specified by LowerBound.
Array numbers = Array.CreateInstance(typeof(double), new int[] { Length }, new int[] { LowerBound });
// Initialize the array.
for (int i = numbers.GetLowerBound(0); i <= numbers.GetUpperBound(0); i++)
{
numbers.SetValue(i, i);
}
var variable = LabVIEWExports.Multiply(numbers, 2); // This is invalid as numbers is not typed double[*].
Console.ReadKey();
在C#中签名LabVIEW函数
更新2
尝试使用C#的Reflection用以下代码调用LabVIEW函数,但遇到TargetInvocationException
。
const int Length = 5;
const int LowerBound = 1;
const string methodName = "MultiplyArray";
const string path = @"C:\";
Array numbers = Array.CreateInstance(typeof(double), new int[] { Length }, new int[] { LowerBound });
for (int i = numbers.GetLowerBound(0); i <= numbers.GetUpperBound(0); i++)
{
numbers.SetValue(i, i);
}
Assembly asm = Assembly.LoadFile(path + "LabVIEW.Interop.dll");
Type type = asm.GetType("LabVIEW.Interop.LabVIEWInteropExports");
if (type != null)
{
MethodInfo methodInfo = type.GetMethod(methodName);
if (methodInfo != null)
{
object result = methodInfo.Invoke(methodInfo, new object[] { array, multiplicand }); // Throw exception.
}
}
Console.ReadKey();
内部异常消息
Unable to cast object of type 'System.Double[*]' to type 'System.Double[]'.
内部异常堆栈跟踪
at NationalInstruments.LabVIEW.Interop.DataMarshal.InitMarshalArrayIn(IntPtr data, Array array, Marshal1DArray val)
at LabVIEW.Interop.LabVIEWInteropExports.MultiplyArray(Double[*] input__32Array, Int32 numeric)
似乎在执行的某个时刻,程序试图在LabVIEW附带的程序集中使用double[*]
函数将类型double[]
封送到InitMarshalArrayIn()
。
答案 0 :(得分:3)
.NET支持非零索引的数组。 C#没有语法来编写此类型,但您可以使用Array.CreateInstance
创建它。
接下来,使用反射来调用 LabVIEWExports.Multiply
并传递您创建的数组。
答案 1 :(得分:3)
我不确定我是否应将此作为答案,但在此处:
碰巧这是与Visual Studio 2015相关的问题,因为我正在使用Visual Studio Community 2015 Update 1.有关详细信息,请参阅this和this。
答案 2 :(得分:1)
如果您使用dynamic
(而不是诉诸反射),它会起作用,如下一行:
const int Length = 5;
const int LowerBound = 1;
// Instanstiate a non-zero indexed array. The array is one-dimensional and
// has size specified by Length and lower bound specified by LowerBound.
var numbers = Array.CreateInstance(typeof(double), new int[] { Length }, new int[] { LowerBound });
// Initialize the array.
for (int i = numbers.GetLowerBound(0); i <= numbers.GetUpperBound(0); i++)
{
numbers.SetValue(i, i);
}
var variable = (Array)LabVIEWExports.Multiply((dynamic)numbers, 2);
变量numbers
具有编译时类型Array
到C#,因为C#没有double[*]
的语法。但也许dynamic
可以正常运行时numbers
的实际类型应该是正确的,所以可能后期绑定到正确的方法会有效吗?