Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# .NET

Войти
Регистрация
Восстановить пароль
 
Dimestel
6 / 6 / 0
Регистрация: 02.07.2011
Сообщений: 65
#1

Unsafe код из с++ на с# - C#

28.08.2011, 00:46. Просмотров 897. Ответов 3
Метки нет (Все метки)

Не уверен в той ли ветке пишу вопрос, но может кто знает.. есть код на ++ необходимо создать аналог на шарпе. Этот код является аналог представления списков на visual prolog в с++(или там откуда будет вызываться предикат) - нужен для вызова предиката из длл написаснной на прологе.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
typedef struct i_wrapper {
 unsigned char is_eolist;
 int  data;
 struct i_wrapper *next;
} iwrapper;
 
extern "C" void __stdcall  get_length_of_list (i_wrapper *, int *);
void main (void){
 iwrapper * pointee_in = NULL;
 int number;
 do{
 printf ("enter number? ");
 scanf ("%d" , &number);
 iwrapper *iw = new iwrapper;
 iw->data = number;
 iw->is_eolist = 1;
 iw->next = pointee_in;
 pointee_in = iw;
 }while (number != 0);
 
 iwrapper *iw = pointee_in;
 while (iw->next)
 iw = iw->next;
 iw->is_eolist = 2;
 int size;
 get_length_of_list (pointee_in , &size);
 printf ("size = %d\n" , size);
}
на всякий приведу код пролога если кому поможет но если в общих словах предикат из пролога принимает на вход список- но просто так передать его нельзя как int[] - нужно именно так как тут показано
Prolog
1
2
3
4
get_length_of_list ([] , 0):-!.
  get_length_of_list ([H|T] , N):-!,
    get_length_of_list (T , N1),
    N = 1 + N1.
1
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.08.2011, 00:46
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Unsafe код из с++ на с# (C#):

.NET 4.x BitmapData и unsafe-код - C#
Подскажите пожалуйста, как мне с помощью указателей добраться до отдельного пикселя в изображении и получить уже с этого пикселя значения...

Error 1 Unsafe code may only appear if compiling with /unsafe - C#
Как исправить ошибку Error 1 Unsafe code may only appear if compiling with /unsafe ? как скомпилить с модификатором unsafe?

Unsafe code и NullReferenceException - C#
Добрый день. Столкнулся с этой проблемой уже давно и понять ее, как бы я не пытался - не могу. Есть бот, большая часть которая...

Определить unsafe ли? динамически подгружаемой сборки - C#
имеем System.Reflaction.Assembly с метаданными сборки, как опраделить стоит ли на сборке unsafe аттрибут?

Почему время выполнения unsafe и обычного кода примерно одинаково - C#
Почему-то скорость выполнения сложных операций в с матрицами, элементы которых лежать в одномерном массиве получилась одинаковой для Unsafe...

небезопасный код (unsafe) - C#
Столкнулся с проблемой: Visual Studio 2010 ругается на unsafe, а именно: "ошибка CS0227: Небезопасный код может использоваться только при...

3
NickoTin
Почетный модератор
Эксперт .NET
8246 / 3528 / 239
Регистрация: 14.06.2010
Сообщений: 4,510
Записей в блоге: 9
28.08.2011, 02:48 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Так попробуйте:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System;
using System.Runtime.InteropServices;
 
namespace ConsoleApplication6
{
    class Program
    {
        [DllImport( "PrologDllName" )]
        unsafe static extern void get_length_of_list (
            iwrapper* wrapper,
            int* size
            );
 
        [StructLayout( LayoutKind.Sequential/*, Pack = 1 */ )]
        unsafe struct iwrapper
        {
            public byte is_eolist;
            public int data;
            public iwrapper *next;
 
            unsafe public static iwrapper* Alloc ( ) {
                return (iwrapper*)Marshal.AllocHGlobal( Marshal.SizeOf( typeof( iwrapper ) ) );
            }
 
            unsafe public static void Free ( iwrapper* wrapper ) {
                if ( wrapper == null )
                    return;
 
                wrapper->FreeNext();
                Marshal.FreeHGlobal( (IntPtr)wrapper );
            }
 
            unsafe public void FreeNext ( ) {
                if ( this.next != null ) {
                    this.next->FreeNext();
                    Marshal.FreeHGlobal( (IntPtr)this.next );
                    this.next = null;
                }
            }
        }
 
        unsafe static void Main ( string[] args ) {
            iwrapper *pointee_in = null,
                iw = null;
            int number = 0,
                size = 0;
 
            do {
                Console.WriteLine( "enter number? " );
                if ( !int.TryParse( Console.ReadLine(), out number ) ) {
                    Console.WriteLine( "invalid number" );
                    number = -1;
                    continue;
                }
                iw = iwrapper.Alloc();
                iw->data = number;
                iw->is_eolist = 1;
                iw->next = pointee_in;
                pointee_in = iw;
            } while ( number != 0 );
 
            iw = pointee_in;
            while ( iw->next != null )
                iw = iw->next;
            iw->is_eolist = 2;
 
            get_length_of_list( pointee_in, &size );
            Console.WriteLine( "size = {0}\n", size );
 
            if ( pointee_in != null ) {
                iwrapper.Free( pointee_in );
                pointee_in = null;
            }
        }
    }
}
3
Dimestel
6 / 6 / 0
Регистрация: 02.07.2011
Сообщений: 65
28.08.2011, 13:42  [ТС] #3
спасибо огромное, все работает!
0
Dimestel
6 / 6 / 0
Регистрация: 02.07.2011
Сообщений: 65
06.09.2011, 21:32  [ТС] #4
честно говоря сейчас вобще не знаю куда писать - попробую пока сюда.. если ошибся - то переместите тему куда уместнее.
все работает - могу передать список, число, получить число, а вот с приемом списка возникли проблемы. по предикату, возвращающему список он может либо вернуться без изменений (4 элемента), либо на 1 элемент меньше. Но почему то при возврате я получаю во первых инвертированный список (не знаю тонкостей работы с указателями и ссылками), во вторых вместо значения последнего элемента я получаю число 9600 Оо - косяк возникает не всегда, зависимостей не выявил, но когда возникает, то 99% это будет 9600 число - и несмотря на то что этот элемент как и положено имеет значение is_eolist = 2 (признак конца структуры) но указатель на след элемент не пустой а содержит какой-то адрес, и возможно следующий элемент по этому адресу тоже содержит еще один указатель не пустой. приведу вначале код предиката пролога - ниже выложу результат работы данного предиката в прологе же, потом код на шарпе и результаты работы.
Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
global domains
    int = integer
    il = int*
global predicates
    procedure logic(int,il,il,int,il,int)  - (i,i,i,o,o,o) language stdcall 
predicates
    stand(int,il,il)
    p(int,il,il,il)
logic(CScore,Hand,MD,ResCScore,ResHand,ResPass):-stand(CScore,Hand,Hand_res),
        compare(Hand,Hand_res), prb_sum(CScore,MD),
        ResCScore=CScore, ResHand=Hand_res, ResPass=0,!.
%собственно этот предикат вызывается, но список меняет (или нет) предикат stand
stand(CScore,L,Ans):-p(CScore,[],L,Ans).
 
    p(CScore,Prev,[H|T],Ans):-CScore+H=20,append(Prev,T,Ans),!.
    p(CScore,Prev,[H|T],Ans):-append(Prev,[H],Prev1),p(CScore,Prev1,T,Ans),!.
    p(_,Prev,[],Prev):-!.
    
    append([],L2,L2).
    append([H|T1],L2,[H|T3]):-append(T1,L2,T3).
%остальное думаю не относится к задаче
результат работы пролога при вызове предиката logic(7,[-4,-5,1,-2],[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 4, 5, 6, 8, 9,10],X,Y,Z).

X=7, Y=[-4,-5,1,-2], Z=0
1 Solution
как видите список вернулся без изменений. для еще большего уточнения и пояснения покажу что именно stand отвечает за изменение или нет списка (запускаю его с теми же параметрами, которые он получил бы при вызове из logic:
stand(7,[-4,-5,1,-2],Hand_res).

Hand_res=[-4,-5,1,-2]
1 Solution
смысл данного предиката (принимает параметры CScore,Hand, возвращает Hand_res - результирующий список): сравнивает сумму CScore и каждого элемента из списка Hand со значением 20, если не равно то перегнать число из списка Hand в результирующий список Hand_res. как только сумма станет равной то весь хвост списка (оставшиеся элементы без текущего, сумма с которым дала 20) перегнать в результат, например : stand(7,[-4,-5,1,-2],Hand_res). Hand_res=[-4,-5,1,-2].
stand(15,[-4,5,1,5],Hand_res). Hand_res=[-4,1,5].

вот значит. с прологом разобрались переходим в студию.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//структура осталась без изменений
[StructLayout(LayoutKind.Sequential/*, Pack = 1 */ )]
        unsafe struct iwrapper
        {
            public byte is_eolist;
            public int data;
            public iwrapper* next;
 
            unsafe public static iwrapper* Alloc()
            {
                return (iwrapper*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(iwrapper)));
            }
 
            unsafe public static void Free(iwrapper* wrapper)
            {
                if (wrapper == null)
                    return;
 
                wrapper->FreeNext();
                Marshal.FreeHGlobal((IntPtr)wrapper);
            }
 
            unsafe public void FreeNext()
            {
                if (this.next != null)
                {
                    this.next->FreeNext();
                    Marshal.FreeHGlobal((IntPtr)this.next);
                    this.next = null;
                }
            }
        }
 
[DllImport("Pazaak_logic.dll", CharSet = CharSet.Auto)]
        unsafe static extern void logic(int cScore, iwrapper* hand, iwrapper* md, int* resCScore, iwrapper** resHand, int* resPass);
 
int[] rs = new int[4];
                iwrapper* cHand = null,
                    iw = null;
                //ClassInterfaceFunc.Score(ClassVar.cTable);
                //int pass = 0;
                iwrapper* pointee = null, resHand = null;
                pointee = resHand;
 
                int resCScore;
                int resPass;
 
                int data = 0;
                int i = 0;
                do
                { // создаю список Hand для передачи в пролог
                    data = ClassVar.cHand[i];
                    i++;
                    iw = iwrapper.Alloc();
                    iw->data = data;
                    iw->is_eolist = 1;
                    iw->next = cHand;
                    cHand = iw;
                } while (i != ClassVar.cHand.Length);
 
                iw = cHand;
                while (iw->next != null)
                    iw = iw->next;
                iw->is_eolist = 2;
 
                iwrapper* mainDeck = null,
                zz = null;
                int data1 = 0;
                int p = 0;
                do
                { // тут еще один список делаю, в принципе к вопросу отношения он не имеет 
                    data1 = ClassVar.mainDeck[p];
                    p++;
                    zz = iwrapper.Alloc();
                    zz->data = data1;
                    zz->is_eolist = 1;
                    zz->next = mainDeck;
                    mainDeck = zz;
                } while (p != ClassVar.mainDeck.Length);
 
                zz = mainDeck;
                while (zz->next != null)
                    zz = zz->next;
                zz->is_eolist = 2;
 
 /* attantion! */   logic(ClassInterfaceFunc.Score(ClassVar.cTable), cHand, mainDeck, &resCScore, &pointee, &resPass); // вызываю сам предикат - скрин прилагается - использованы теже параметры что и в примере на прологе
//  после прохода и получается тот несуразный список - результат в скрине
                //Console.WriteLine("size = {0}\n", size);
                int z = 0;
                while (pointee->is_eolist == 1 || pointee->is_eolist == 2)
                {
                    rs[z] = pointee->data;
                    z++;
                    pointee = pointee->next;
                }
                Console.WriteLine("size = {0}, {1} \n", resCScore, resPass);
                if (cHand != null)
                {
                    iwrapper.Free(cHand);
                    cHand = null;
                }
0
Миниатюры
Unsafe код из с++ на с#   Unsafe код из с++ на с#  
06.09.2011, 21:32
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.09.2011, 21:32
Привет! Вот еще темы с ответами:

Переделать unsafe код в safe - C#
Есть реализация криптоалгоритма Xtea с использованием unsafe кода. Как передалать его в safe? Фрагмент, который нужно переделать. ...

Unsafe code only allowed in unsafe procedure - Delphi
Доброго времени! Писал программу листинг к-ого program Project2; {$APPTYPE CONSOLE} {$UNSAFECODE ON} {$T-} uses SysUtils; ...

Компилируется ли unsafe-код в машинные инструкции - C#
Компилируется ли такой код в машинные инструкции или все же в IL? Заранее благодарен.

DllImport, unsafe код, указатель на функцию - C#
Необходимо вызвать функцию из dll, у которой параметром является структура, в которой одно из полей - указатель на функцию. Я не знаю, как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru