Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > создание статической DLL


Автор: AngelDominantes 27.7.2010, 10:18
всем доброго времени суток, сразу к делу:
при попытке создать статическую ДЛЛ возникает вот такая вот ошибка: [Linker Error] Error: Unresolved external 'Message(char *)' referenced from C:\BORLAND STUDIO PROJECTS\UNIT1.OBJ
текст DLL, заголовочного файла и тест приложения ниже:
DLL 
Код

#include <vcl.h>
#include <windows.h>
#include "MyDLL.h"
#pragma hdrstop

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    return 1;
}
void Message(char *s) {
    Application->MessageBox(s,"From DLL",IDOK);
}


MyDLL.h
Код

#if defined(BUILD_DLL)
# define DLL_EXP __declspec(dllexport)
#else
# if defined(BUILD_APP)
# define DLL_EXP __declspec(dllimport)
# else
# define DLL_EXP
# endif
#endif

DLL_EXP void Message(char *s);

Test programm
Код

#include "MyDLL.h"
#include "Unit1.h"
#include <vcl.h>
#include <stdio.h>
#pragma comment(lib, "Project1.lib")

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

    Message("Hello world");

}


Такое ощущение что не цепляется lib файл, даже если его добавить в проект руками результат тот же. . . грешу на настройки buildra юзаю DBS 2006
Заранее благодарен.

Автор: EnergoHokum 27.7.2010, 10:28
DLL -- dynamic linked library. Не находишь противоречие уже в самой формулировке: "статическая динамически подключаемая..."?

Автор: AngelDominantes 27.7.2010, 10:49
Существует еще и статическое связывание DLL

Автор: Abyx 27.7.2010, 11:58
AngelDominantes, это называется статический импорт из DLL

Автор: EnergoHokum 27.7.2010, 12:33
Цитата

Существует еще и статическое связывание DLL

Так ты-ж сам пишешь, что создаёшь и подключаешь не DLL, а вовсе даже lib. А статические и динамические библиотеки в потрохах сильно различаются.

Автор: AngelDominantes 27.7.2010, 12:48
Так я выложил все потроха, программа использует функцию из ДЛЛ которая выводит в messageboxe "Hello world", чего может быть проще?! человек хоть раз столкнувшись с этим понял бы все с полувзгляда, но в итоге ни одного комментария по существу, какие то придирки к терминологии, это так модно нынче?

Автор: EnergoHokum 27.7.2010, 12:57
Цитата

какие то придирки к терминологии

Компилятор делает не то, что ты от него хочешь, а то, что ты ему говоришь. Поэтому вопросы терминологии должны быть прояснены до блеска. Это не религия какая-нить, где "чуда не случилось, т. к. прихожане плохо веровали".

Теперь по существу вопроса: когда ты создаёшь проект библиотеки -- ты вызываешь DLL Wizard, или Library?

DBS 2006 у меня нет, есть замшелый Builder 6. Да и тот -- на работе. Поэтому как уйду домой -- подсматривать будет вообще некуда.

Автор: Modul 27.7.2010, 13:03
А ты случайно не забыл в папку проекта положить 2 файла:
myDLL.lib
myDLL.dll


А импорт кто будет добавлять в проект (это пример):

Код

#define DLLIMPORT extern "C" __declspec(dllimport)
DLLIMPORT int summa(int x);



Автор: AngelDominantes 27.7.2010, 13:27
Конечно DLL wizard, Алгоритм такой я создаю DLL, компилирую, lib файл созданной dll подключаю к программе, так же прописываю заголовочный файл от dll, и вызываю тупо функции в своей программе которые описаны в dll. . .

Автор: EnergoHokum 27.7.2010, 13:35
Ну, тогда http://www.safer-networking.org/ru/filealyzer/index.html посмотреть, есть ли в DLL экспорт нужной функции, им-же посмотреть, есть ли в *.lib описание этой функции. Если и там, и там всё в порядке -- ну, тогда не знаю, настройки IDE ковырять надо, может, в ней подключение как-то неочевидно делается...

Автор: AngelDominantes 27.7.2010, 13:45
Цитата(Modul @ 27.7.2010,  13:03)
А ты случайно не забыл в папку проекта положить 2 файла:
myDLL.lib
myDLL.dll


А импорт кто будет добавлять в проект (это пример):

Код

#define DLLIMPORT extern "C" __declspec(dllimport)
DLLIMPORT int summa(int x);

я думал будет достаточно только Lib,  а импорт описан  в заголовочном файле dll или его еще и в основной проект нужно прописывать?

Автор: borisbn 27.7.2010, 13:48
Определены ли в dll и exe defin'ы BUILD_DLL и BUILD_APP соответственно ?
С каких пор Builder понимает 
Цитата

#pragma comment(lib, "Project1.lib")

Я закончил работать с версией 5.0, там нужно было в проект ( !!! ) добавлять lib-файл.

Автор: AngelDominantes 27.7.2010, 13:54
Так lib добавлен, даже если 
Код

#pragma comment(lib, "Project1.lib")

не работает я добавлял его вручную.
а смысл в exe определять 
Цитата(borisbn @  27.7.2010,  13:48 Найти цитируемый пост)
BUILD_DLL и BUILD_APP

если я подключаю заголовочный файл 
Код

#if defined(BUILD_DLL)
# define DLL_EXP __declspec(dllexport)
#else
# if defined(BUILD_APP)
# define DLL_EXP __declspec(dllimport)
# else
# define DLL_EXP
# endif
#endif
DLL_EXP void Message(char *s);

где они определены

Автор: bsa 27.7.2010, 14:48
#pragma hdrstop лучше ставить стразу после #include <vcl.h>, который должен быть первой строкой - компилироваться будет быстрей

Автор: borisbn 27.7.2010, 15:34
а смысл в exe определять только BUILD_APP, чтобы 
Цитата

DLL_EXP void Message(char *s);

стала
Цитата

__declspec(dllimport) void Message(char *s);

Автор: AngelDominantes 28.7.2010, 12:40
Для этого достаточно подключить заголовочный файл, что я собственно и сделал. . .

Автор: borisbn 28.7.2010, 13:47
Цитата(AngelDominantes @  28.7.2010,  12:40 Найти цитируемый пост)
Для этого достаточно подключить заголовочный файл

нет. не достаточно, потому, что в заголовочном файле проверяется, что если определён BUILD_DLL, то DLL_EXP превращается в __declspec(dllexport), а если определён BUILD_APP, то в __declspec(dllimport). Если же ты ничего не определил, то DLL_EXP определяется как пусто. Просто добавь в проект приложения
#define BUILD_APP 
и будет счастье smile

Автор: AngelDominantes 5.8.2010, 09:24
Дабы не плодить темы спрошу тут:

Код

#if defined(_DLLMAINCPP)
#  define DLL_SPEC __declspec(dllexport)
#else
# if defined(_APPMAINCPP)
#  define DLL_SPEC __declspec(dllimport)
# else
#  define DLL_SPEC
# endif
#endif

extern "C" DLL_SPEC bool OutlookHook(int,int,int);
extern "C" DLL_SPEC void SetHook();
extern "C" DLL_SPEC void UnHook();

вот такой вот заголовочный файл ДЛЛ, но при просмотре данной ДЛЛ tdump выдает 

Код

Exports from HookDLL.dll
  1 exported name(s), 1 export addresse(s).  Ordinal base is 1.
  Sorted by Name:
    RVA      Ord. Hint Name
    -------- ---- ---- ----
    000020F8    1 0000 ___CPPdebugHook

то есть он не подставляет вместо DLL_SPEC __declspec(dllexport) если забить напрямую все начинает работать, в чем может быть причнина?

Автор: borisbn 5.8.2010, 12:47
99 % в том, что в проекте dll-ки не определён _DLLMAINCPP. Посмотри в свойствах проекта в разделе Directories/Conditionals/Conditional defines

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)