Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5636 / 790 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 14:

Совмещение управляемого и неуправляемого кодов

< Лекция 13 || Лекция 14: 12345 || Лекция 15 >

Пример. Указание набора символов в C#

Поле DllImportAttribute.CharSet определяет набор символов как базовый набор ANSI или Unicode. Набор символов определяет режим выполнения маршалинга строковых аргументов. Для указания набора символов применяется один из следующих вариантов атрибута:

[DllImport("dllname", CharSet=CharSet.Ansi)]
 [DllImport("dllname", CharSet=CharSet.Unicode)]
 [DllImport("dllname", CharSet=CharSet.Auto)]

В следующем примере показаны три управляемых определения функции MessageBox с атрибутами, задающими наборы символов. В первом определении, в котором значение поля CharSet не задано, по умолчанию принимается набор символов ANSI:

[DllImport("user32.dll")]
     public static extern int MessageBoxA(int hWnd, String text, 
       String caption, uint type);

 [DllImport("user32.dll", CharSet=CharSet.Unicode)]
     public static extern int MessageBoxW(int hWnd, String text, 
       String caption, uint type);

 [DllImport("user32.dll", CharSet=CharSet.Auto)]
     public static extern int MessageBox(int hWnd, String text,
       String caption, uint type);

Примеры платформного вызова. MessageBox, Beep, PlaySound

Под ПЛАТФОРМОЙ НАЗНАЧЕНИЯ понимается платформа, которой предназначена закодированная в атрибутах информация. Естественно, это .NET.

В других платформах службы платформного вызова нет. Никакая другая платформа просто не сумеет прочитать и понять значение полей атрибутов.

Ниже демонстрируется определение и вызов функции MessageBox из библиотеки User32.dll. В качестве аргумента передается простая строка. Значение для атрибута поля DllImportAttribute.CharSet установлено в Auto. Это позволяет платформе назначения самостоятельно определять размер символов и выбирать маршалинг строк:

using System.Runtime.InteropServices;

public class Win32 {
      [DllImport("user32.dll", CharSet=CharSet.Auto)]
      public static extern int MessageBox(int hWnd, String text, 
                    String caption, uint type);
 }

public class HelloWorld {
     public static void Main() {
      Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);
     }
 }

Информация о функции Beep в хелпах по C# отсутствует. Такой функции в .NET НЕТ. Однако способы заставить C#-приложение "пропищать" все же существуют (передача функции Console.Writeline параметра с соответствующей escape-последовательностью не в счет).

Итак, функция

Beep

обеспечивает генерацию simple tones (простых звуков) на спикере. Функция выполняется синхронно; она не возвращает управления до тех пор, пока не завершится звучание.

BOOL Beep(
   DWORD dwFreq,
   DWORD dwDuration
 );

Параметры

dwFreq

Частотная характеристика звука в герцах. Диапазон значений этого параметра ограничен следующими величинами 37–32,767 ( 0x25– 0x7FFF ).

В Windows Me/98/95 функция Beep этот параметр игнорирует.

dwDuration

Продолжительность звучания в миллисекундах.

В Windows Me/98/95 функция Beep этот параметр игнорирует.

Возвращаемое значение

Здесь речь идет о неуправляемой функции, судя по всему, реализованной в C++. Так вот, при успешном выполнении функция возвращает ненулевое значение. В C++ такие значения соответствуют значению ИСТИНА.

В противном случае возвращается нулевое значение, то есть ЛОЖЬ:

using System;
 using System.Threading;
 using System.Runtime.InteropServices;

namespace BeepByWin32API
 {

 // Import a Beep() API function.

class Class1
 {
 // Таким образом получаем возможность использования импортируемых
 // функций в приложении .NET.

 [DllImport("kernel32.dll")]
 private static extern bool Beep(int frec, int dur);
 // Импортируется функция PlaySound().
 [DllImport("winmm.dll")]
 public static extern bool PlaySound(string pszSound,
                                        int hmod,
 			                     int fdwSound);
 // Константы, необходимые для использования PlaySound...
 public const int SND_FILENAME = 0x00020000;
 // За конкретное значение параметра я не ручаюсь. Подобрал сам.
 // Играет - и ладно...
 public const int SND_ASYNC = 0x0010;//0x0001;
 		

 // The main entry Point for the application.

 static void Main(string[] args)
 {
 int i;
 // Извлекаем звук посредством escape-последовательности.
 Console.WriteLine("Пропищим..." + "\a\a\a\a\a\a\a\a\a\a");
 Console.WriteLine("И еще...");
 for (i = 0; i < 10; i++) {Console.Write("\a"); Thread.Sleep(1000);}

Console.WriteLine("Нажми Any Key для продолжения опытов...");
 Console.ReadLine(); 
 // Извлекаем звук посредством обращения к функции API Beep().
 // Frequency of the sound, in hertz.
 // This parameter must be in the range 37 through 32,767 (0x25 through 0x7FFF). 
 // Duration of the sound, in milliseconds. 
 Beep(800,200);
 Beep(500,1000);
 Beep(100,500);
 Beep(1000,2000);
 Beep(0x25,2000);
 Beep(0x7FFF,2000);

Console.WriteLine("Нажми Any Key для продолжения опытов...");
 Console.ReadLine(); 
for (i = 0; i < 10; i++)
 {
 PlaySound("Trumpet1.wav", 0, SND_FILENAME|SND_ASYNC);
 }

 }
 }
 }
Листинг 14.2.
< Лекция 13 || Лекция 14: 12345 || Лекция 15 >
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2