• Программинг

Нужны источники бесперебойного питания?

Источники бесперебойного питания от дизельстор

Создание .NET-библиотеки для использования в WIN32-приложениях или как подключить библиотеку на C# к Delphi.

В жизни каждого программиста всегда происходит какая-то фигня, когда нужно выполнить поставленную задачу и заказчика не волнует как это будет сделано. Вот и случилось так, что нужно было написать dll-файл и подключить к проекту, написанному на Delphi. Но, т.к. я терпеть не могу паскаль и люблю C#, то было принято решение написать библиотеку на C# и каким-то образом подключить ее к проекту на делфях года этак 2005. В итоге задача была успешно решена. Каким образом…? Читайте дальше.

В Visual Studio создаем новый проект ClassLibrary, задаем ему вымышленное имя testwin32.

22

1 ...
2 using System.Runtime.InteropServices;
3  
4 public interface IMyInterface
5 {
6     int Sum(int x, int y);
7     string AppendText(string text);
8 }
9  
10 [ClassInterface(ClassInterfaceType.None)]
11 public class TestClass : IMyInterface
12 {
13     //просто суммируем два числа
14     public int Sum(int x, int y)
15     {
16         return x + y;
17     }
18  
19     //к следующему тексту добавляем текущий год
20     public string AppendText(string text)
21     {
22         StringBuilder sb = new StringBuilder(text);
23         sb.Append(DateTime.Now.Year);
24         return sb.ToString();
25     }
26 }

Класс содержит два метода: первый возвращает сумму двух чисел; второй просто добавляет к строке какой-то текст.
Для того, чтобы методы были видны, требуется описать интерфейс и добавить в using System.Runtime.InteropServices. Класс наследуется от интерфейса IMyInterface и для класса описываем аргумент [ClassInterface(ClassInterfaceType.None)]. В самом интерфейсе вы описываете только те методы, которые будут видны «снаружи». Если в классе находятся другие методы, то в интерфейсе их описывать не обязательно (они будут работать внутри класса).
Следующим шагом будет подготовка проекта к компиляции. Для этого в меню Project выберите свойство проекта (Properties).

23

В открывшемся окне в Application нажмите на кнопку Assembly Information… В появившемся окне установите галочку напротив свойства Make assembly COM-visible – для того, чтобы ваша информации о библиотеке была общедоступна.

24

Далее на вкладке Build установите галочку напротив свойства Register for COM interop.

25

Теперь все готово к компиляции. Выполните компиляцию и перейдите в папку с созданным файлом.
Перед использованием файла в проекте Delphi, его нужно подготовить.
Утилитой regasm нужно создать tlb-файл. Сама утилита обычно находится в папке c:\Windows\Microsoft.NET\Framework\v2.0.50727\

1 regasm testwin32.dll /tlb:testwin32.tlb

dll-Библиотека рядом с exe-файлом программы.
Давайте подготовим небольшую программу на Delphi, которая будет использовать нашу библиотеку. Я использую Delphi 6. Создадим новый проект. В проект скопируем файл – testwin32.dll.

Если вы уже регистрировали библиотеку, то при компиляции в Visual Studio вместе с dll-файлом, сразу появляется и tlb-файл с таким же названием

В Delphi заходим в меню Project->Import Type Library. В появившимся окне выбираем testwin32 и нажимаем кнопку Create Unit. Если testwin32 в списке нет, то через кнопку Add находим tlb-файл.

26

Обратите внимание, если вы все правильно до этого сделали, то в списке классов, при добавлении библиотеки, вы увидите название своего класса

В коде по нажатию кнопок пишем следующий код:

1 ...
2 uses
3   ComObj, testwin32_TLB;
4 {$R *.dfm}
5  
6 procedure TForm1.btnSumClick(Sender: TObject);
7 var
8   intfRef: IMyInterface;
9   result: Integer;
10 begin
11   intfRef := CreateComObject(CLASS_TestClass) as IMyInterface;
12   result := intfRef.Sum(StrToInt(Edit1.Text), StrToInt(Edit2.Text));
13   lblSum.Caption := IntToStr(result);
14 end;
15  
16 procedure TForm1.btnTextClick(Sender: TObject);
17 var
18   intfRef: IMyInterface;
19 begin
20   intfRef := CreateComObject(CLASS_TestClass) as IMyInterface;
21   lblText.Caption := intfRef.AppendText(Edit3.Text);
22 end;

В uses главного юнита допишите:

1 uses
2   ComObj, testwin32_TLB;

testwin32_TLB – название юнита, который сгенерировался автоматически при добавлении библиотеки. Функция CreateComObject(CLASS_TestClass) as IMyInterface принимает название нашего класса, название которого строиться по схеме CLASS_ххххх.

Бывает так, что в файле mscorlib_TLB возникает ошибка типа Type ‘Byte’ is not yet completely defined. Исправляется она добавлением к каждому типу, строки «System.». Т.е. у вас должно получиться «System.Byte». Замените все ошибки и сохраните проект

Пример работы программы, которая использует библиотеку на C#.

27

UPDATE 1
Если вы ставите галочку напротив Register for COM interop и Make assembly COM-Visible, тогда Visual Studio регистрирует вашу библиотеку в системе автоматически. Для работы в другой системе вам необходимо убрать обе отметки и вручную зарегистрировать библиотеку. Для этого измените часть кода, представленный в примере:

1 [ClassInterface(ClassInterfaceType.None)]
2 public class TestClass : IMyInterface
3 ...

на

1 [ComVisible(true),ClassInterface(ClassInterfaceType.None)]
2 public class TestClass : IMyInterface
3 ...

К интерфейсу добавьте атрибут:

1 [ComVisible(true)]
2 public interface IMyInterface
3 ...

И выполните команду регистрации:

1 RegAsm.exe xxx.dll /codebase /tlb: xxx.tlb

Спасибо Сергею, за инфу.

Заключение

В этой статье мы рассмотрели как можно подключить написанную на C# библиотеку к приложению Win32. Как это все работает наглядно вы можете посмотреть в тестовом проекте, который прилагается к статье.