Przekazanie obiektu String do procedury MASM

0

Czy istnieje możliwość przekazania Tablicy lub Stringu jako argumentu do procedury napisanej w MASMie? Jeśli tak, to jak rozwiązać taki problem?
Procedura napisana w MASMie znajdowałaby się w osobnej bibliotece dll.

0

Normalny marshalling, tak jak przy komunikacji z C, C++ czy z Delphi.
Od strony C# wygląda to jak zwykła tablica albo string, a od strony natywnej jako wskaźnik.

0

Szczerze mówiąc, nigdy wcześniej nie zajmowałem się czymś takim. Wyszukałem taki przykład:

[DllImport("StringLib.Dll")]
public static extern void
PassLPWStr([MarshalAs(UnmanagedType.LPWStr)]String s);

gdzie:
UnmanagedType.LPWStr - A pointer to a null-terminated array of Unicode characters.

I dzięki temu dostane tablice zakończoną NULLem, po której w procedurze w MASMie mógłbym "poruszać się po znakach"?

1

I dzięki temu dostane tablice zakończoną NULLem, po której w procedurze w MASMie mógłbym "poruszać się po znakach"?
Dostaniesz wskaźnik do tablicy zakończonej znakiem \0. W tej postaci tablica będzie tylko do odczytu, tj. istniejący string musi być przekazany z C#, a w MASMie nie powinieneś go modyfikować (a zmiany nie będą odzwierciedlone w C#).

LPWStr oznacza stringa w UTF-16 (dwa bajty na znak).
Jeśli chcesz dostać zwykły tekst ASCII/ANSI (w bieżącej stronie kodowej) użyj LPStr.

0

A co musiałbym zrobić, żeby zwrócić nowy napis? Napisałem coś takiego:
[DllImport("bibliotekaASM.dll", CallingConvention = CallingConvention.StdCall)]
private static extern String szyfruj([MarshalAs(UnmanagedType.LPStr)]String s1, [MarshalAs(UnmanagedType.LPStr)]String s2, int length_s1, int length_s2);

W masmie "edytuje" przekazaną jako parametr tablice, ale ta edycja nie jest widoczna po wyjściu z masma (String przekazany jako parametr pozostał bez zmian), ale gdy zwracam wskaźnik to w nowym Stringu mam właśnie te zedytowaną tablice:) I w sumie chciałbym tu zakończyć całą historie, ale pojawił się problem. Moj visual 2010 w wersji debug i w wersji release bardzo ładnie się zachowuje, tylko gdy uruchomię program za pomocą pliku exe w wersji release, to przy wykorzystaniu procedury z masma wyrzuca mi error:

An unhandled exception of type 'System.AccessViolationException' occurred in WindowsFormsApplication1.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Wie ktoś w czym może być problem?

1

Nie ma chyba dobrego sposobu na zwrócenie stringa, bo pojawia się problem kto (i jak, i kiedy) miałby zaalokować a potem zwolnić bufor.

Ale możesz przekazać StringBuilder jako dodatkowy parametr.

Czyli coś takiego:

StringBuilder sb = new StringBuilder(256); // rozmiar bufora
funkcja_z_asma(coś, tam, sb, 256); // funkcja wypełnia bufor sb, więdząc że ma 256 znaków
String s = sb.ToString();
0

Rozumiem że sb też przesłać z pomocą marshallingu?

I czy wtedy sposób poruszania się po tablicy i szkic procedury mógłby wyglądać następująco?

 
nazwa proc uses EDI ESI ECX EDX EBX cos:dword, tam:dword, sb:dword, size:dword

      mov ebx, sb

;poczatek petli

;edycja 

      mov [ebx], eax ; w eax wynik edycji
      inc ebx

;koniec petli (wykonana 256 razy)

ret
nazwa endp

Edit: Zrealizowałem to w taki sosób:

Dllka w masmie na takiej samej zasadzie jak powyżej.
Sygnatura funkcji:

        [DllImport("bibliotekaASM.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern void funkcja([MarshalAs(UnmanagedType.LPStr)]String s1, [MarshalAs(UnmanagedType.LPStr)]String s2, [MarshalAs(UnmanagedType.LPStr)]StringBuilder s3,int length_s1, int length_s2);
 

Wywołanie:

 
            String text = this.richTextBox1.Text;
            String klucz = this.richTextBox3.Text;
            int length_text = this.richTextBox1.Text.Length;
            int length_klucz = this.richTextBox3.Text.Length;
            StringBuilder sb = new StringBuilder(length_text);
            funkcja(text, klucz, sb, length_text, length_klucz);
            this.richTextBox2.Text = sb.ToString();

1 użytkowników online, w tym zalogowanych: 0, gości: 1