我正试图调用我从一些C#编写的一些C++(也是我的代码(,但在Interop/PInvoke获取已填充的int[]
时遇到了问题。有没有一种方法可以让我从C#项目中添加一个对C++项目的编译时引用,并调用其中的函数,就好像它只是另一个C#类库一样?
我有一个基本的示例来说明数组的问题。这是我正在调用的C++函数的C#签名。
[DllImport("CPlusPlusTargetLibrary.dll", CallingConvention = CallingConvention.StdCall)]
private static extern void Accumulate
(
int input,
int accumulationFactor,
int numberOfAccumulations,
[In, Out, MarshalAs(UnmanagedType.LPArray)]
int[] accumulationsPointer
);
这就是从C#调用它的方式:
var numberOfAccumulations = 3;
var accumulations = new int[numberOfAccumulations];
Accumulate(-8, 1, numberOfAccumulations, accumulations);
这是它在C++头文件中的声明:
__declspec(dllexport) const void __stdcall Accumulate
(
const signed long input,
const signed long accumulationFactor,
const signed long numberOfAccumulations,
signed long* accumulationsPointer
);
这是它在C++中的实现:
__declspec(dllexport) const void __stdcall Accumulate
(
const signed long input,
const signed long accumulationFactor,
const signed long numberOfAccumulations,
signed long* accumulationsPointer
)
{
for (auto index = 0; index < numberOfAccumulations; index++, accumulationsPointer++)
{
auto accumulation = input * ((index + 1) * accumulationFactor);
accumulationsPointer = &accumulation;
}
}
accumulations
数组只是作为所有0
的3元素数组返回,就像它被传入一样。相反,它应该包含-8
、-16
和-24
。
我遵循了MSDN上关于封送int[]
的文档,根据它,我不应该需要任何手动封送(但即使去掉MarshalAs
属性也无法解决问题(:https://learn.microsoft.com/en-us/dotnet/framework/interop/marshaling-different-types-of-arrays
我曾希望,如果我可以直接引用C++项目,那么我就不必处理所有与类型相关的运行时故障。
您的代码不写入accumulationsPointer
的内容,而是用accumulation
的地址覆盖指针本身
它应该是类似于这个的东西
for (auto index = 0; index < numberOfAccumulations; index++, accumulationsPointer++)
{
auto accumulation = input * ((index + 1) * accumulationFactor);
*accumulationsPointer = accumulation;
}
或类似的,如c#
for (auto index = 0; index < numberOfAccumulations; ++index)
{
auto accumulation = input * ((index + 1) * accumulationFactor);
accumulationsPointer[index] = accumulation;
}
btw,signed long* accumulationsPointer
也可以写成signed long accumulationsPointer[]
,例如
void Accumulate
(
const signed long input,
const signed long accumulationFactor,
const signed long numberOfAccumulations,
signed long accumulations[]
)
{
for (auto index = 0; index < numberOfAccumulations; ++index)
{
auto accumulation = input * ((index + 1) * accumulationFactor);
accumulations[index] = accumulation;
}
}