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

2 |
using System.Runtime.InteropServices; |
4 |
public interface IMyInterface |
7 |
string AppendText(string text); |
10 |
[ClassInterface(ClassInterfaceType.None)] |
11 |
public class TestClass : IMyInterface |
14 |
public int Sum(int x, int y) |
20 |
public string AppendText(string text) |
22 |
StringBuilder sb = new StringBuilder(text); |
23 |
sb.Append(DateTime.Now.Year); |
Класс содержит два метода: первый возвращает сумму двух чисел; второй просто добавляет к строке какой-то текст.
Для того, чтобы методы были видны, требуется описать интерфейс и добавить в using System.Runtime.InteropServices. Класс наследуется от интерфейса IMyInterface и для класса описываем аргумент [ClassInterface(ClassInterfaceType.None)]. В самом интерфейсе вы описываете только те методы, которые будут видны «снаружи». Если в классе находятся другие методы, то в интерфейсе их описывать не обязательно (они будут работать внутри класса).
Следующим шагом будет подготовка проекта к компиляции. Для этого в меню Project выберите свойство проекта (Properties).

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

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

Теперь все готово к компиляции. Выполните компиляцию и перейдите в папку с созданным файлом.
Перед использованием файла в проекте 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-файл.

Обратите внимание, если вы все правильно до этого сделали, то в списке классов, при добавлении библиотеки, вы увидите название своего класса
В коде по нажатию кнопок пишем следующий код:
6 |
procedure TForm1.btnSumClick(Sender: TObject); |
11 |
intfRef := CreateComObject(CLASS_TestClass) as IMyInterface; |
12 |
result := intfRef.Sum(StrToInt(Edit1.Text), StrToInt(Edit2.Text)); |
13 |
lblSum.Caption := IntToStr(result); |
16 |
procedure TForm1.btnTextClick(Sender: TObject); |
18 |
intfRef: IMyInterface; |
20 |
intfRef := CreateComObject(CLASS_TestClass) as IMyInterface; |
21 |
lblText.Caption := intfRef.AppendText(Edit3.Text); |
В uses главного юнита допишите:
testwin32_TLB – название юнита, который сгенерировался автоматически при добавлении библиотеки. Функция CreateComObject(CLASS_TestClass) as IMyInterface принимает название нашего класса, название которого строиться по схеме CLASS_ххххх.
Бывает так, что в файле mscorlib_TLB возникает ошибка типа Type ‘Byte’ is not yet completely defined. Исправляется она добавлением к каждому типу, строки «System.». Т.е. у вас должно получиться «System.Byte». Замените все ошибки и сохраните проект
Пример работы программы, которая использует библиотеку на C#.

UPDATE 1
Если вы ставите галочку напротив Register for COM interop и Make assembly COM-Visible, тогда Visual Studio регистрирует вашу библиотеку в системе автоматически. Для работы в другой системе вам необходимо убрать обе отметки и вручную зарегистрировать библиотеку. Для этого измените часть кода, представленный в примере:
1 |
[ClassInterface(ClassInterfaceType.None)] |
2 |
public class TestClass : IMyInterface |
на
1 |
[ComVisible(true),ClassInterface(ClassInterfaceType.None)] |
2 |
public class TestClass : IMyInterface |
К интерфейсу добавьте атрибут:
2 |
public interface IMyInterface |
И выполните команду регистрации:
1 |
RegAsm.exe xxx.dll /codebase /tlb: xxx.tlb |
Спасибо Сергею, за инфу.
Заключение
В этой статье мы рассмотрели как можно подключить написанную на C# библиотеку к приложению Win32. Как это все работает наглядно вы можете посмотреть в тестовом проекте, который прилагается к статье.