Sl@Sh |
Отправлено: 06.04.2005, 10:07 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
Здравствуйте уважаемые ! Вот возникла проблема при компиляции ДЛЛ
Подскажите пожалуйста! Вот что я делал :
CODE |
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include <Graphics.hpp>
//Тут функция входа.....
//Экспортирую функцию
extern "C" __declspec(dllexport) void Func()
{
TCanvas *Cnv = new TCanvas;
//.................
delete Cnv;
}
|
Выдаётся ошибка линкера :
CODE |
[Linker Error] Unresolved external '__fastcall Graphics::TCanvas::~TCanvas()' referenced from D:\PROGRAMMING\BASE\C++\BCB\GraphDLL\Main.obj
[Linker Error] Unresolved external 'Graphics::TCanvas::' referenced from
D:\PROGRAMMING\BASE\C++\BCB\GraphDLL\Main.obj
[Linker Error] Unresolved external '__fastcall Graphics::TCanvas::TCanvas()' referenced from D:\PROGRAMMING\BASE\C++\BCB\GraphDLL\Main.obj
|
Если функцию не экспортировать, а написать просто
CODE |
void Func()
{
TCanvas *Cnv = new TCanvas;
//.................
delete Cnv;
}
|
То всё ОК !
P.S.: Мне кажется, что я не правильно экспортирую функцию. Подскажите пож. как правильно.
Заранее благодарен !
|
|
mlind |
Отправлено: 06.04.2005, 12:34 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 7
|
Попробуй так:
//mydll.h
#define DLL_SPEC extern "C" __export
DLL_SPEC void mess();
//mydll.cpp
void DLL_SPEC mess()
{
...
}
|
|
** Sl@Sh |
Отправлено: 06.04.2005, 12:51 |
|
Не зарегистрирован
|
Чел. ты гений ! Я забыл про хеадер файл !!! Спасибо !!!!!!!!!!!!!! |
|
Sl@Sh |
Отправлено: 06.04.2005, 15:58 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
Беру свои слова назад
Объявил в неад-файле, и снова те-же ошибки ! Самое прикольное, что
библиотека компилится (и даже работает !) если использовать пакеты.
Вот выкладываю проект, чтобы ясней была ситуация :
Header.h
CODE |
#ifndef __HEADER_H
#define __HEADER_H
#if defined(__cplusplus)
extern "C"
{
#endif
__declspec(dllexport) void Func(Graphics::TBitmap *sourceBMP);
#if defined(__cplusplus)
}
#endif
#endif
|
Main.cpp
CODE |
//----------------------------------------------------------------------------//
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "Header.h"
#include <Graphics.hpp>
//----------------------------------------------------------------------------//
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//----------------------------------------------------------------------------//
void Func(Graphics::TBitmap *sourceBMP)
{
sourceBMP->Monochrome = true; // Просто для примера
}
//----------------------------------------------------------------------------//
|
Названия функции и её предназначение взяты чисто для примера, однако параметр, передаваемый функции такой и должен быть.
Отредактировано Sl@Sh — 06/04/2005, 16:07
|
|
avc* |
Отправлено: 06.04.2005, 16:04 |
|
Не зарегистрирован
|
Я обычно так пишу -
extern "C" __declspec(dllexport) bool SomeFun(int iparam);
bool SomeFun(int iparam)
{...
}
|
|
Sl@Sh |
Отправлено: 06.04.2005, 16:11 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
QUOTE (avc* @ 06/04/2005, 16:04) | Я обычно так пишу -
extern "C" __declspec(dllexport) bool SomeFun(int iparam);
bool SomeFun(int iparam)
{...
} |
В том-то и дело, что подобный код работает, а если использовать в функции операции с TBitmap или TCanvas — выдаются ошибки
|
|
Asher |
Отправлено: 06.04.2005, 17:29 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Не факт что при объявлении интефейса как extern "C" в объявлении можно использовать не "С"-типы.
Попробуй заменить на void* с последующим приведением.
По хорошему так поступать нельзя — но в качестве эксперимента стоит проверить.
P.S. а зачем именно extern "C" ? предполагается использование из различных программ?
Отредактировано Asher — 06/04/2005, 18:30
|
|
AVC |
Отправлено: 07.04.2005, 09:50 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Пары — описание и параметр GetProcAddress
CODE |
extern "C" __declspec(dllexport) TQuickRep* GetQuickRep (bool needcreate, TDataSet *ds)
"_GetQuickRep"
__declspec(dllexport) TQuickRep* GetQuickRep (bool needcreate, TDataSet *ds)
"@GetQuickRep$qop11Db@TDataSet"
PACKAGE TQuickRep* __fastcall GetQuickRep (bool needcreate, TDataSet *ds)
"@GetQuickRep$qqrop11Db@TDataSet"
|
external в первом варианте пишу в отдельной строке — были какие-то заморочки с bpl/dll, а это вылечило. |
|
Sl@Sh |
Отправлено: 07.04.2005, 15:19 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
QUOTE (Asher @ 06/04/2005, 17:29) | P.S. а зачем именно extern "C" ? предполагается использование из различных программ? |
Вы правы, extern "C" не нужен т.к. програ одна.
to AVC — буду пробовать
P.S.: Интерестно, а почему всё работает если использовать пакеты ?
|
|
AVC |
Отправлено: 07.04.2005, 16:43 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
Интерестно, а почему всё работает если использовать пакеты ?
|
Приведенные примеры — рабочие.
PACKAGE стоит в bpl (это по вашему пакет?)
остальное в dll |
|
xim |
Отправлено: 07.04.2005, 16:46 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 143
|
В bpr-файле, теге packages должны быть прописаны vcl*.bpi файлы. Если их нет, то нужно добавить их ручками или пересоздать проект с использованием VCL. Для DLL Wizard => опция "Use VCL" |
|
Sl@Sh |
Отправлено: 08.04.2005, 15:12 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
to xim — библиотека так и создана (Use VCL)
|
|
xim |
Отправлено: 08.04.2005, 18:57 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 143
|
QUOTE (Sl@Sh @ 06/04/2005, 10:07) |
Если функцию не экспортировать, а написать просто
CODE |
void Func()
{
TCanvas *Cnv = new TCanvas;
//.................
delete Cnv;
}
|
То всё ОК !
|
Дело в том, что при описании функции в DLL поиск менглов в описаниях библиотек (*.lib, ...), по которым в проекте идет работа с объектными данными, производится только при наличии спецификаций типа extern "prog_lang". Скорее всего косяк именно в BPR (см. выше). "Use VCL" — просто предположение — похоже ошибка в другом месте. |
|
Sl@Sh |
Отправлено: 09.04.2005, 11:57 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
В эту библиотеку я предполагал добавить форму. Без формы всё благополучно не работало, а теперь (когда форма добавлена) всё работает !
Правда я пересоздал библиотеку заново. Возможно та была создана неверно.
|
|
xim |
Отправлено: 12.04.2005, 09:16 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 143
|
Пробуем подключить (к проекту без формы) vcl60.lib (у меня в 5 версии vcl50.lib -> в 6 версии должен быть vcl60.lib ) |
|
Sl@Sh |
Отправлено: 17.04.2005, 18:19 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
Забыл всех поблагодарить за ответы : Большое спасибо !
Правда проблема не решена, буду искать решение
|
|
FataLL |
Отправлено: 18.04.2005, 00:14 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 37
|
Может, попробовать создать длл со статическими библиотеками?
|
|
Sl@Sh |
Отправлено: 18.04.2005, 16:01 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
Вы имеете ввиду пакеты (runtime packages) ?
С ними всё компилится, и даже работает. Только это делает библиотеку зависимой от машины.
|
|
Sl@Sh |
Отправлено: 19.04.2005, 15:30 |
|
Мастер участка
Группа: Участник
Сообщений: 383
|
QUOTE (xim @ 12/04/2005, 09:16) | Пробуем подключить (к проекту без формы) vcl60.lib (у меня в 5 версии vcl50.lib -> в 6 версии должен быть vcl60.lib ) |
Спасибо xim ! Это помогло. Просто я не сразу прочитал ваш ответ.
Всем спасибо за участие. Тему можно считать закрытой
P.S.: В 6-ом билдере — vcl.lib
Отредактировано Sl@Sh — 19/04/2005, 15:31
|
|