DLL экспортируют функции по имени и порядковому значению.Каждый из них должен быть уникальным.Вы не можете экспортировать две разные функции с одинаковыми именами или одинаковыми порядковыми номерами.
Ваш пример с InterlockedExchangeAdd
- это просто две функции с разными, но эквивалентными сигнатурами, относящимися к одной и той же функции.Это сделано для удобства звонящего.
Давайте оставим порядковый номер в одну сторону и сконцентрируемся на именах.Из первого абзаца очень ясно, что вы должны использовать разные имена для каждой функции.Конечно, вы все равно можете использовать внутреннюю перегрузку, но указывать разные имена как часть предложения экспортаАналогично, при импорте вы можете объявить импортированные функции как перегруженные, но для указания имени DLL используйте синтаксис имени.
Итак, в общем, вы можете легко использовать внутреннюю перегрузку с обеих сторон интерфейса, но вы должныиспользуйте уникальные имена при экспорте и импорте функций.Вот простой пример:
Библиотека, которая экспортирует функции
library liba;
procedure F(X: Integer); stdcall; overload;
begin
end;
procedure F(X, Y: Integer); stdcall; overload;
begin
end;
exports
F(X: Integer) name 'F1',
F(X, Y: Integer) name 'F2';
begin
end.
Библиотека, которая импортирует функции
library libb;
procedure F(X: Integer); stdcall; overload; external 'liba.dll' name 'F1';
procedure F(X, Y: Integer); stdcall; overload; external 'liba.dll' name 'F2';
begin
end.
Ключевое слово overload
может появляться в любом месте объявления.Неважно, где это появляется.С другой стороны, соглашение о вызовах должно появиться до external
.
Обратите внимание, что языки, которые не поддерживают перегрузку (например, VB6, C), очевидно, не смогут импортировать функции и использовать те же именадля них.Аналогично для языков, которые не поддерживают переименование функции при импорте (например, C ++).Насколько я знаю, только Delphi допускает такие аккуратные приемы во время импорта.
Для таких языков, как C ++ и C #, которые поддерживают перегрузку, вам потребуется ввести еще один уровень косвенности.Например, в C # вы должны сделать это:
[DllImport("liba.dll")]
private static extern void F1(int X);
[DllImport("liba.dll")]
private static extern void F2(int X, int Y);
public static void F(int X)
{
F1(X);
}
public static void F(int X, int Y)
{
F2(X, Y);
}
Точно такой же подход может быть использован в C ++.Единственная реальная разница между этим подходом и кодом Delphi, который я показал выше, заключается в том, что язык Delphi поддерживает прямой синтаксис для выполнения этого отображения.
Что касается различных примеров в вашем вопросе, то все они используют строку, которая изКонечно, это частный тип Delphi.Вы не должны использовать string
в экспортируемой функции, если функция должна вызываться из любого языка, кроме Delphi.Или, действительно, любая версия компилятора, отличная от той, с которой вы создали DLL.