Вызов C ++ DLL из C # неверно оценивает ULLONG_MAX - PullRequest
0 голосов
/ 18 октября 2018

Не эксперт в C ++.Я сделал C ++ DLL (из примера MSDN), которая делает простую последовательность Фибоначчи в C ++.Я тогда называю это из C #.Большинство функций работают нормально, за исключением того, что функция finoacci_next () должна возвращать true, когда происходит переполнение целых чисел.В библиотеке C ++ это условие (ULLONG_MAX - previous_

DLL заголовка C ++

// MathLibrary.h - Contains declarations of math functions
#pragma once

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif

// The Fibonacci recurrence relation describes a sequence F
// where F(n) is { n = 0, a
//               { n = 1, b
//               { n > 1, F(n-2) + F(n-1)
// for some initial integral values a and b.
// If the sequence is initialized F(0) = 1, F(1) = 1,
// then this relation produces the well-known Fibonacci
// sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
extern "C" MATHLIBRARY_API void fibonacci_init(
    const unsigned long long a, const unsigned long long b);

// Produce the next value in the sequence.
// Returns true on success and updates current value and index;
// false on overflow, leaves current value and index unchanged.
extern "C" MATHLIBRARY_API bool fibonacci_next();

// Get the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned long long fibonacci_current();

// Get the position of the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned fibonacci_index();

C ++ DLL

// MathLibrary.cpp : Defines the exported functions for the DLL.
#include "stdafx.h"
#include <utility>
#include <limits.h>
#include "MathLibrary.h"

// DLL internal state variables:
static unsigned long long previous_;  // Previous value, if any
static unsigned long long current_;   // Current sequence value
static unsigned index_;               // Current seq. position

                                      // Initialize a Fibonacci relation sequence
                                      // such that F(0) = a, F(1) = b.
                                      // This function must be called before any other function.
void fibonacci_init(
    const unsigned long long a,
    const unsigned long long b)
{
    index_ = 0;
    current_ = a;
    previous_ = b; // see special case when initialized
}

// Produce the next value in the sequence.
// Returns true on success, false on overflow.
bool fibonacci_next()
{
    // check to see if we'd overflow result or position
    if ((ULLONG_MAX - previous_ < current_) ||
        (UINT_MAX == index_))
    {
        return false;
    }

    // Special case when index == 0, just return b value
    if (index_ > 0)
    {
        // otherwise, calculate next sequence value
        previous_ += current_;
    }
    std::swap(current_, previous_);
    ++index_;
    return true;
}

// Get the current value in the sequence.
unsigned long long fibonacci_current()
{
    return current_;
}

// Get the current index position in the sequence.
unsigned fibonacci_index()
{
    return index_;
}

C # интерфейс

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// Allow managed code to call unmanaged functions that are implemented in a DLL
using System.Runtime.InteropServices;

namespace TestingCallingCPP_FromCSharp
{
    class Program
    {
        [DllImport("C:\\Users\\Adam\\source\\repos\\MathLibrary\\Debug\\MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void fibonacci_init(ulong a, ulong b);
        [DllImport("C:\\Users\\Adam\\source\\repos\\MathLibrary\\Debug\\MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool fibonacci_next();
        [DllImport("C:\\Users\\Adam\\source\\repos\\MathLibrary\\Debug\\MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern ulong fibonacci_current();
        [DllImport("C:\\Users\\Adam\\source\\repos\\MathLibrary\\Debug\\MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)] // is this the right type for unsigned long long
        public static extern uint fibonacci_index();


        static void Main(string[] args)
        {

            // Initialize a Fibonacci relation sequence.
            fibonacci_init(1, 1);
            // Write out the sequence values until overflow.
            do
            {
                Console.Write(fibonacci_index() + ": " + fibonacci_current() +""+ Environment.NewLine);
            } while (fibonacci_next());
            // Report count of values written before overflow.
            Console.Write((fibonacci_index() + 1) + " Fibonacci sequence values fit in an " +
                "unsigned 64-bit integer." + Environment.NewLine);
            Console.ReadLine();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...