代码之家  ›  专栏  ›  技术社区  ›  zar

如何通过引用将C++中的int传递给C++?

  •  1
  • zar  · 技术社区  · 5 年前

    是否可以通过引用将C中的int传递给C++?

    我有一个简单的方法,在C++中只增加一个数字和打印消息。

    void ProcessOrder(int& num)
    {
        int start = num;
        int stop = num + 10;
    
        for (int i = start; i < stop; i++)
        {
            cout << "[Legacy] counting " << i << endl;
        }
    
        cout << endl;
    
        // Note the above was original posted code and I made a stupid mistake and was never
        // even changing `num` value passed by reference. The correct function to test
        // should be as below (discard all of the above)
        num =  num + 5; // just modify the number to any value
    }
    

    现在我想从C++和CLI调用这个,然后从C语言调用。

    void StoreWrapper::ProcessOrder(int^ num)
    {
        LegacyStore* legacyStore = new LegacyStore();
        legacyStore->ProcessOrder(num); // error here
    }
    

    但这将返回编译器错误:

    error C2664: 'void LegacyStore::ProcessOrder(int &)': cannot convert argument 1 from 'System::Int32 ^' to 'int &'
    

    我确保这三个项目都是x86,但错误仍然存在。价格方面,CLR模块是Win32,C控制台应用程序是x86。

    问题在于:

    如果我宣布 void StoreWrapper::ProcessOrder(int& num)

    error CS1503: Argument 1: cannot convert from 'int' to 'int*'
    

    如果我声明它为“void StoreWrapper::ProcessOrder(int^num)”,那么该方法甚至不会编译。

    我试过用 System::Int32

    更新

    C代码在这里,基本上我想在下面的代码中更新这个数字。

      int number = 0;
      Console.WriteLine("Original number = {0}", number);
      store.ProcessOrder(ref number);
      Console.WriteLine("After ProcessOrder number = {0}", number);
    

    不幸的是,dxiv的答案没有更新上面的数字。

    0 回复  |  直到 5 年前
        1
  •  0
  •   dxiv    5 年前

    尝试使用 num 直接喜欢 ProcessOrder(num); 由于原文中引用的错误而失败“ 无法从转换参数1 System::Int32 ^ int & “因为传递的(指针)变量和预期的(引用)参数之间的间接寻址级别不同。

    ProcessOrder(*num); 更正间接寻址并获取要匹配的类型,但编译失败,并出现错误“ gc堆中的对象(未绑定的值类型)无法转换为本机引用 ". 这指出了真正的问题,即非托管/未绑定的引用不能指向gc托管堆,这会受到压缩和重新洗牌的影响。

    最简单的解决方案是使用 tracking reference int% answer 与作为副本链接的问题。

    void StoreWrapper::ProcessOrder(int% num)
    {
        LegacyStore* legacyStore = new LegacyStore();
    
        legacyStore->ProcessOrder(*&num);  // shorthand for:
                                           //
                                           // int &n = *&num;
                                           // legacyStore->ProcessOrder(n);
                                           // num = n;
    }
    
    // to be called from C# as:
    //
    // int number = 0;
    // store.ProcessOrder(ref number);
    
    


    [ ]也可以使用 号码
    void StoreWrapper::ProcessOrder([System::Runtime::InteropServices::Out] int %num)
    {
        LegacyStore* legacyStore = new LegacyStore();
    
        pin_ptr<int> p = &num;
        legacyStore->ProcessOrder(*p);
    }
    
    // to be called from C# as:
    //
    // int number = 0;
    // store.ProcessOrder(out number);
    


    [ 编辑#2 ]编辑代码并添加注释,以涵盖将值返回给C调用方。
    推荐文章