【问题标题】:Is it possible to reference a C++ project from a C# project?是否可以从 C# 项目中引用 C++ 项目?
【发布时间】:2021-04-17 12:26:31
【问题描述】:

我正在尝试调用一些我从一些 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://docs.microsoft.com/en-us/dotnet/framework/interop/marshaling-different-types-of-arrays

我曾希望如果我可以直接引用 C++ 项目,那么我就不必处理所有与类型相关的运行时故障。

【问题讨论】:

  • 仅当它是托管 C++ 时,我猜它不是。
  • 将 C++ 转换为托管 C++ 的工作量可能与将​​ C++ 转换为 C# 的工作量大致相同。
  • 发布相关的代码片段,包括被调用的导出 C++ 函数和 C# 调用者。
  • 嗯,这是一个想法。我不使用 C++,所以得知 C++ 中的 long 是 32 位时我很惊讶。
  • c++代码accumulationsPointer = &amp;accumulation;不应该是*accumulationsPointer = accumulation;吗?

标签: c# c++ project-reference compile-time-type-checking


【解决方案1】:

您的代码不会写入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;            
}

顺便说一句,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;            
   }
}

【讨论】:

    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多