Я пишу DLL C/C++ и хочу экспортировать определенные функции, которые я сделал перед использованием .def файла как это
LIBRARY "MyLib"
EXPORTS
Foo
Bar
с кодом, определенным как это, например:
int Foo(int a);
void Bar(int foo);
Однако, что, если я хочу объявить перегруженный метод Foo () как:
int Foo(int a, int b);
Поскольку файл определения только имеет имя функции а не полный прототип, который я не вижу, как это обработало бы перегруженные функции. Вы просто используете одну запись и затем определяете, который перегрузил версию, которую Вы хотите при передаче в правильно смоделированном указателе функции LoadLibrary ()?
Править: Чтобы быть ясным, это находится в Windows с помощью Visual Studio 2005
Править: Отмеченный неопределение (__ declspec) метод как ответ... Я знаю, что это на самом деле не решает проблему с помощью файлов определения, как я хотел, но кажется, что там не вероятно никакое (официальное) решение с помощью файлов определения. Оставит вопрос открытым, однако, в случае, если кто-то знает что-то, что у нас нет файлов определения и перегруженных функций.
В самом коде отметьте функции, Вы хотите экспортировать использование __ declspec (dllexport). Например:
#define DllExport __declspec(dllexport)
int DllExport Foo( int a ) {
// implementation
}
int DllExport Foo( int a, int b ) {
// implementation
}
Если Вы делаете это, Вы не должны перечислять функции в .def файле.
С другой стороны, Вы можете использовать значение параметра по умолчанию, как:
int Foo( int a, int b = -1 )
Это предполагает, что там существует значение для b, который можно использовать, чтобы указать, что это не использовано. Если-1 будет легальное значение для b, или если не будет или не должно будет быть значением по умолчанию, то это не будет работать.
Редактирование (Adam Haile): Исправленный для использования __ declspec в качестве __ dllspec не был корректен, таким образом, я мог отметить это как официальный ответ... это было достаточно близко.
Редактирование (Graeme): ой - благодарит исправить мою опечатку!
Нет никакого официального способа сделать то, что Вы хотите, потому что интерфейс dll является API C.
Сам компилятор использует скорректированные имена в качестве обходного решения, таким образом, необходимо использовать искажение имени, когда Вы не хотите изменяться слишком много в Вашем коде.
Перегрузка функции является функцией C++, которая полагается на искажение имени (загадочные имена функций в сообщениях об ошибках компоновщика).
Путем записи скорректированных имен в файл определения я могу получить свой тестовый проект связаться и работать:
LIBRARY "TestDLL"
EXPORTS
?Foo@@YAXH@Z
?Foo@@YAXHH@Z
кажется, работает на
void Foo( int x );
void Foo( int x, int y );
Так скопируйте имена функций C++ с сообщения об ошибке и запишите им в Ваш файл определения. Однако реальный вопрос: Почему Вы хотите использовать файл определения и не пойти с __ declspec (dllexport)?
Скорректированные имена являются непортативными, я протестировал с VC ++ 2008.
Нет агностика языка или версии способа экспортировать перегруженную функцию, так как конвенция искажения может измениться с каждым релизом компилятора.
Это - одна причина, почему большинство функций WinXX имеет забавные имена как *Исключая или *2.
У меня была подобная проблема, таким образом, я хотел отправить на этом также.
Обычно использование
extern "C" __declspec(dllexport) void Foo();
экспортировать имя функции прекрасно. Это будет обычно экспортировать имя, неискаженное без потребности в .def файле. Существуют, однако, некоторые исключения как __ stdcall имена перегруженной функции и функции.
Если Вы объявляете, что функция использует __ stdcall конвенция (как сделан для многих API-функций), затем
extern "C" __declspec(dllexport) void __stdcall Foo();
экспортирует скорректированное имя как _Foo@4. В этом случае Вы, возможно, должны явно отобразить экспортируемое имя к внутреннему скорректированному имени.
A. Как экспортировать неискаженное имя. В .def файле добавляют
----
EXPORTS
; Explicit exports can go here
Foo
-----
Это попытается найти "лучшее соответствие" для внутренней функции Foo и экспортировать его. В случае выше, где существует только одно нечто, это создаст отображение
Нечто = _Foo@4
как может быть, посмотрите через dumpbin / ЭКСПОРТ
При перегрузке имени функции затем, Вы, возможно, должны явно сказать, какую функцию Вы хотите в .def файле путем определения скорректированного имени с помощью entryname [=internalname] синтаксис. например.
----
EXPORTS
; Explicit exports can go here
Foo=_Foo@4
-----
B. Альтернатива .def файлам - то, что можно экспортировать имена "на месте" с помощью #pragma.
#pragma comment(linker, "/export:Foo=_Foo@4")
C. Третья альтернатива должна объявить всего, что одна версия Foo как экстерн "C" экспортируется неискаженная. Посмотрите здесь для деталей.