Popou
@Popou
Программист энтузиаст , обожаю саморефлексию

Почему не получается преобразовать __int128 в BigInteger в своей функции?

я далеко не силен в c и особо не силен в p/invoke, и для практики я решил проверить себя...... подозреваю что нужно использовать malloc(кажется просто возвращается адрес памяти или читает лишние байты), но тогда стоит вопрос об использование free.
код на C:
#include <stdint.h>

__int128  fact(int  n)
{
    if (n == 0) return 1;
    return n * fact(n - 1);
}

__int128* ptr_fact(int n)
{
    __int128 val = fact(n);
    __int128* pfact = &val;
    return pfact;
}

Код на c#:
[DllImport("Test")] static extern IntPtr ptr_fact(int n);

BigInteger ToBigInteger(IntPtr ptr)
{
    Span<byte> span;
    unsafe
    {
        span = new(ptr.ToPointer(), 16);
    }
    return new(span);
}

а вот результат:
64097eeb0b4d3916413556.png
  • Вопрос задан
  • 148 просмотров
Решения вопроса 2
1. Ты берёшь указатель на переменную на стеке, которая после выхода из него уже не факт, что будет иметь то значение, которое тебе нужно.
2. Тебе нужно выделить память заранее (или в куче) и в эту область памяти уже записывать результат.
3. Лучше, чтобы память для результата выделялась на стороне C#, чтобы не было проблем с освобождением памяти.
4. Сишный int не всегда равен шарповому int.
5. В .NET уже есть структура для Int128, так что тебе не нужно байты перекладывать.

6.
public BigInteger (ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);
принимает байты от длинного целого. Так что у тебя твой ToBigInteger работает неправильно, если ты в него подаёшь указатель, на __int128

ptr_fact должно выглядеть как-то так:
void ptr_fact(int32_t n, __int128* result)
{
    *result = fact(n);
}

[DllImport("Test")] static extern void ptr_fact(int n, out Int128 result);


Но смысла использовать ptr_fact я не вижу, тк обычный fact ты тоже легко можешь вызывать
Ответ написан
Popou
@Popou Автор вопроса
Программист энтузиаст , обожаю саморефлексию
просто использовал malloc, но теперь беда с утечкой памяти)
код на c
__int128* ptr_fact(int n)
{
    __int128* pfact = malloc(sizeof(__int128));
    *pfact = fact(n);
    return pfact;
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
Проще на Сишарпе факториал посчитать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы