C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Неизвестные (для меня) ошибки, DLL
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



Беру свои слова назад sad.gif

Объявил в неад-файле, и снова те-же ошибки ! Самое прикольное, что
библиотека компилится (и даже работает !) если использовать пакеты.

Вот выкладываю проект, чтобы ясней была ситуация :
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 — буду пробовать smile.gif

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) sad.gif
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 smile.gif )
Sl@Sh
Отправлено: 17.04.2005, 18:19


Мастер участка

Группа: Участник
Сообщений: 383



Забыл всех поблагодарить за ответы : Большое спасибо !

Правда проблема не решена, буду искать решение sad.gif
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  smile.gif  )

Спасибо xim ! Это помогло. Просто я не сразу прочитал ваш ответ.

Всем спасибо за участие. Тему можно считать закрытой smile.gif

P.S.: В 6-ом билдере — vcl.lib

Отредактировано Sl@Sh — 19/04/2005, 15:31

Вернуться в Вопросы программирования в C++Builder