Страница 2 из 4

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 11:25
Absurd
Создал пустой dll проект в MSVC 6
добавил в него def файл (никак его не регистрировал)

Код: Выделить всё

LIBRARY   BBB_TEST
DESCRIPTION "Discussion issue from developing.ru"
EXPORTS
   func1   @1
   func2   @2
Написал ХЭ файл (bbb_test.h)

Код: Выделить всё

#ifndef __BBB_TEST_H_INCLUDED
#define __BBB_TEST_H_INCLUDED

extern "C" {
	void func1(int arg1, char** arg2);
	void func2(int arg1, char** arg2);
};
#endif

написал ЦПП файл

Код: Выделить всё

#include "stdafx.h"
#include "bbb_test.h"

void func1(int arg1, char** arg2) {
}

void func2(int arg1, char** arg2) {
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}
Откомиплировал получил bbb_test.dll

Создал другой проект, кинул туда dll файл в корень и прошелся дебагером

Код: Выделить всё

HMODULE hModule = LoadLibrary("bbb_test.dll");
int (*func)(int, char) = (int (*)(int, char))GetProcAddress(hModule, "func1");
FreeLibrary(hModule);
GetProcAddress отработал нормально.

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 11:47
Hawk
То что экспортируется в lib файле не связано с тем что ты в DEF файле пропишешь. Лучше всего явно экспортировать функции как "С" (хороший пример у Absurd-a выше), а в lib файле ты все равно получишь эти функции с префиксами. Чего ты там в def файле не пиши на lib это никак не повлияет.
А там, где ты хочешь lib линковать, просто обьявляешь эти функции как extern "C".
Если посмотреть опять на пример то тебе просто надо инклюднуть "bbb_test.h" в то место где ты хочешь юзать функции из bb_test.dll. Да и прилинковать конечно bbb_test.lib.

ЗЫ все виндовские библиотеки так именно и сделаны, открой любой хидер (ex. WinUser.h) и увидешь одной из первых строчек 'extern "C" { '

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:02
BBB
Absurd писал(а):.....
Создал другой проект, кинул туда dll файл в корень и прошелся дебагером

Код: Выделить всё

HMODULE hModule = LoadLibrary("bbb_test.dll");
int (*func)(int, char) = (int (*)(int, char))GetProcAddress(hModule, "func1");
FreeLibrary(hModule);
GetProcAddress отработал нормально.
Я и не оспаривал, что через GetProcAddress функция находится/вызывается. Вопрос (как уже неоднократно было спрошено) в том, можно ли как раз в данном случае подлинковать DLL статически.

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:05
BBB
Hawk писал(а):То что экспортируется в lib файле не связано с тем что ты в DEF файле пропишешь..., а в lib файле ты все равно получишь эти функции с префиксами. Чего ты там в def файле не пиши на lib это никак не повлияет.
Простите, но категорически не согласен.

Если в DEF-файле написать:

EXPORTS
ExpFunc = _ExpFunc@4

т.е. использовать формат:
entryname =internalname

То и в LIB, и в DLL попадет имя именно ExpFunc, а не _ExpFunc@4

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:33
BBB
Если EXPORT.DLL - собственной разработки и есть возможность ее малость поменять, то такой (извращенный, конечно) способ даст возможность доступа извне как по декорированному имени, так и по недекорированному.
Дублирую точки входа в DEF-файле:

Код: Выделить всё

EXPORTS
  ExpFunc = _ExpFunc@4
 _ExpFunc@4 = _ExpFunc@4

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:41
WinMain
Мне как-то приходилось делать самому некий аналог библиотеки импорта для одной DLL, поскольку готового LIB-файла к ней не прилагалось. Но этот мой "рукописный" LIB-файл фактически выполнял явную загрузку модуля через LoadLibrary() и связь с функциями осуществлял с помощью GetProcAddr(). А уже само приложение, которое использовало мой LIB-файл, просто вызывало те функции-переходники, которые были в нём реализованы. Поскольку имена функций в моём LIB-файле точно совпадали с именами функций, экспортируемых самой DLL, то получался именно тот результат, которого ты так хочешь добиться от своего LIB-файла, создаваемого при сборке DLL. Я даже специальный шаблон для этого сделал, поскольку в системе есть немало модулей, для которых в Platform SDK имеются лишь заголовочные файлы без библиотек импорта.

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:46
Hawk
BBB писал(а):Простите, но категорически не согласен.

Если в DEF-файле написать:

EXPORTS
ExpFunc = _ExpFunc@4

т.е. использовать формат:
entryname =internalname

То и в LIB, и в DLL попадет имя именно ExpFunc, а не _ExpFunc@4
Как у тебя в исходниках DLL обьявлена ExpFunc ???

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:46
Absurd
BBB писал(а):Я и не оспаривал, что через GetProcAddress функция находится/вызывается. Вопрос (как уже неоднократно было спрошено) в том, можно ли как раз в данном случае подлинковать DLL статически.
Не понимаю твое спотыкание на абсолютно ровном месте. MSVC генерирует lib файл вместе с dll. Можно эту фичу убрать - поставить "Don't produce .lib file" в свойствах dll проекта. Можно также сгерерировать lib по dll файлу с помощью implib или подобной утилиты.

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:54
Hawk
BBB писал(а):Простите, но категорически не согласен.

Если в DEF-файле написать:

EXPORTS
ExpFunc = _ExpFunc@4

т.е. использовать формат:
entryname =internalname

То и в LIB, и в DLL попадет имя именно ExpFunc, а не _ExpFunc@4
согласен, имя функции можно поменять, но то, как параметры этой функции будут представленны в lib файле зависят тоьлко от extern "C" это или нет функция, то как она обьявлена в исходниках.
пропишите в исходниках что это extern "C" а в вуа файле просто
EXPORTS
ExpFunc

и будет вам счастье

Re: Имена функций в подцепляемой DLL.

Добавлено: 13 июл 2007, 12:55
BBB
Absurd,
Ты упорно предлагаешь мне изменить что-то в EXPORT.DLL.
Вопрос стоит (и изначально стоял) в обратном.


Hawk,
аналогично.

С передачей параметров у меня все в порядке. (Хотя, если точнее, то до этого дело вообще не доходит, так как линкер не находит функцию без префикса/постфикса. extern "C" дает только то, что к имени функции "в хвост" не добавляются буковки, "кодирующие" собой типы параметров ф-ии; начальный подчерк и постфикс '@<размер параметров>' все равно остаются.