Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];

Вниз

Библиотеки на С++ для Дельфи.   Найти похожие ветки 

 
Drowsy   (2009-02-05 01:25) [0]

Можно на С++ создать библиотеку, которую можно будет в Дельфи использовать?


 
Amoeba ©   (2009-02-05 01:51) [1]

Если популярно, то НЕЛЬЗЯ!


 
Германн ©   (2009-02-05 01:57) [2]

Можно. Если есть понимание.
И даже не очень сложно.


 
Drowsy   (2009-02-05 02:58) [3]

Если есть ссылка на толковую статью или примеры как это делается, буду благодарен.


 
Amoeba ©   (2009-02-05 03:40) [4]


> Германн ©   (05.02.09 01:57) [2]
>
> Можно. Если есть понимание.
> И даже не очень сложно.

Не факт. Истина, как известно,  конкретна. Смотря чего хочет автор вопроса, но есть смутное подозрение, что он имеет в виду как раз то, что невозможно (т.е.  не DLL, а сишная LIB). Это и подразумевалось в моем ответе.

> Если есть ссылка на толковую статью или примеры как это
> делается, буду благодарен.
>

Что конкретно-то  нужно? Все зависит от этого. Если одно - то действительно можно (проще или сложнее), если что-то другое - то на самом деле нельзя.


 
Drowsy   (2009-02-05 03:57) [5]

Нашёл в инете очень полезные функции, но реализованные на С++ очень хитро. Я их загнал в C++Builder и протестировал. Есть желание понять, можно ли организовать библиотеку (или как-нибудь иначе организовать "интерфейс"), чтобы юзать эти функии в своей программе на Дельфи.


 
Amoeba ©   (2009-02-05 04:38) [6]

Можно, но только если под библиотекой понимается DLL. Хотя и здесь не все так однозначно (DLL не должна экспортировать или использовать в параметрах ф-ий классы C++)


 
Drowsy   (2009-02-05 05:20) [7]

Нет, функции DLL ничего не будут экспортировать, кроме кода ошибки, если она произойдет.
Я в одной статье нашёл пример:

"""
Приведем исходный код динамически подключаемой библиотеки, которая называется MyDLL и содержит одну функцию MyFunction, которая просто выводит сообщение.

Сначала в заголовочном файле определяется макроконтстанта EXPORT. Использование этого ключевого слова при определении некоторой функции динамически подключаемой библиотеке позволяет сообщить компоновщику, что эта функция доступна для использования другими программами, в результате чего он заносит ее в библиотеку импорта. Кроме этого, такая функция, точно так же, как и оконная процедура, должна определяться с помощью константы CALLBACK:

MyDLL.h
   #define EXPORT extern "C" __declspec (dllexport)
   EXPORT int CALLBACK MyFunction(char *str);

Файл библиотеки также несколько отличается от обычных файлов на языке C для Windows. В нем вместо функции WinMain имеется функция DllMain. Эта функция используется для выполнения инициализации, о чем будет рассказано позже. Для того, чтобы библиотека осталась после ее загрузки в памяти, и можно было вызывать ее функции, необходимо, чтобы ее возвращаемым значением было TRUE:

MyDLL.c
   #include <windows.h>
   #include "MyDLL.h"

   int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved)
   {
       return TRUE;
   }
   EXPORT int CALLBACK MyFunction(char *str)
   {
       MessageBox(NULL,str,"Function from DLL",MB_OK);
       return 1;
   }

После трансляции и компоновки этих файлов появляется два файла - MyDLL.dll (сама динамически подключаемая библиотека) и MyDLL.lib (ее библиотека импорта).

"""

Попробовал его скомпилировать в C++ Builder-e.
Выкидывает ошибку :
[C++ Error] DDDLLL.cpp(34): E2141 Declaration syntax error

EXPORT int CALLBACK MyFunction !!вот здесь!! (char *str)


 
Anatoly Podgoretsky ©   (2009-02-05 09:14) [8]

> Германн  (05.02.2009 1:57:02)  [2]

Нельзя, классовая модель, менеджер памяти разные.


 
Anatoly Podgoretsky ©   (2009-02-05 09:15) [9]

> Amoeba  (05.02.2009 3:40:04)  [4]

> но есть смутное подозрение, что он имеет в виду как раз то, что невозможно (т.е.  не DLL, а сишная LIB).

А какая разница, если для Дельфи, а не для системы.


 
Drowsy   (2009-02-05 09:51) [10]

.... вроде всё же можно:
http://www.imho.ws/showthread.php?t=123792


 
tesseract ©   (2009-02-05 10:30) [11]


> .... вроде всё же можно:


Конечно можно, хоть для Delphi хоть для VB. Только надо понимать как переменные в памяти храняться.


 
Drowsy   (2009-02-06 09:14) [12]

проблема:
1. Есть библиотека dll скомпилированная в С++билдере
2. Если эту библиотеку использует программа написанная на С++, то всё проходит нормально.
3. А если на Дельфи, то при запуске программы ошибка возникает уже до Application.Initialize;

//---------------------------------------------------------------------------
DLLMAIN.H
//---------------------------------------------------------------------------

#if defined(_DLLMAINCPP)
# define DLL_SPEC __declspec(dllexport)
#else
# if defined(_APPMAINCPP)
# define DLL_SPEC __declspec(dllimport)
#else
# define DLL_SPEC
# endif
#endif
void DLL_SPEC Mess(char *s);

//---------------------------------------------------------------------------
DLLMAIN.CPP
//--------------------------------------------------------
#define _DLLMAINCPP
// обратите на эту строчку внимание
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "dllmain.h"
#pragma argsused

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
void Mess(char* p)
{
Application->MessageBox(p,"From DLL",IDOK);
}
//------------------------------------------------

//------------------------------------------------
В Дельфи:
//------------------------------------------------

unit UPAS;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

procedure Mess(var S : string); stdcall;
var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure Mess(var S : string); external "MYDLL.dll" name "Mess";

procedure TForm1.Button1Click(Sender: TObject);
var S : string;
begin
 S := "Привет!";
 Mess(S);
end;
end.


 
tesseract ©   (2009-02-06 10:12) [13]

про stdcall почему всегда все забывают ?


 
tesseract ©   (2009-02-06 10:12) [14]

Удалено модератором


 
Anatoly Podgoretsky ©   (2009-02-06 10:19) [15]

> Drowsy  (06.02.2009 9:14:12)  [12]

У тебя несовпадение типов в Mess


 
Drowsy   (2009-02-06 11:02) [16]

Может быть и несовпадение.
Только, обнаружил что-то совсем странное.
Мне думалось, что компилятор хотя бы проверяет наличие библиотеки,
(не говоря уже о функциях, типах.. в библиотеке), но
он проглатывает спокойно

procedure Mess(var S : string); external "Любая фигня" name "Mess";


 
Сергей М. ©   (2009-02-06 11:15) [17]


> думалось, что компилятор хотя бы проверяет наличие библиотеки


С какого перепугу-то ?
Delphi не вправе ведь запретить тебе компилить проект для исполнения на другой машине, где тобой предполагвется наличие "любой фигни")


 
Drowsy   (2009-02-06 11:26) [18]

Логично, но..
А зачем тогда указывать название библиотеки, если компилтору он не нужен?


 
Сергей М. ©   (2009-02-06 11:35) [19]

Как это не нужен ?
Нужен !
Но не для проверки наличия, а для размещения соотв.информации в таблице импорта будущего исполняемого модуля.
Эта таблица импорта выходит на сцену в ран-тайм.


 
Сергей М. ©   (2009-02-06 11:37) [20]


> Drowsy


Название DLL говорит само за себя - это динамически связываемая библиотека, т.е. вся фактическая работа с ней осуществляется в ран-тайм.


 
Drowsy   (2009-02-06 11:42) [21]

Хитро.
А вновь созданную библиотеку в системе не надо регистрировать как-нибудь
(в регистрах или ещё как?)


 
Сергей М. ©   (2009-02-06 11:49) [22]

В данном контексте не надо.


 
Drowsy   (2009-02-06 11:55) [23]

Я убрал вообще параметр:

в С++ :

void Mess(void)
{
Application->MessageBox("Messa","From DLL",IDOK);
}

в Дельфи
procedure Mess(); external "MYDLL.dll" name "Mess";

Выбрасывает ошибку:
Project  raised too many consecutive exceptions: application defined exception (code xxxx) at xxxx. Process stopped.


 
Сергей М. ©   (2009-02-06 12:03) [24]

А где соглашения о вызове ?


 
tesseract ©   (2009-02-06 12:05) [25]


> procedure Mess(); external "MYDLL.dll" name "Mess";


procedure Mess(); stdcall; external "MYDLL.dll" name "Mess";


 
Drowsy   (2009-02-06 12:07) [26]

Я же указал:
procedure Mess(); stdcall;


 
Anatoly Podgoretsky ©   (2009-02-06 12:07) [27]

> Drowsy  (06.02.2009 11:26:18)  [18]

Так и необязательно, но тогда будет использоваться позднее связывание.


 
Drowsy   (2009-02-06 12:09) [28]

procedure Mess(); stdcall;
var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure Mess(); stdcall; external "MYDLL.dll" name "Mess";


 
Drowsy   (2009-02-06 12:10) [29]

Выбрасывает ошибку:
Project  raised too many consecutive exceptions: application defined exception (code xxxx) at xxxx. Process stopped.


 
Сергей М. ©   (2009-02-06 12:13) [30]

А что показывает отладчик при пошаговой трассировке ?


 
Drowsy   (2009-02-06 12:18) [31]

program PASPro;

uses
 Forms,
 UPAS in "UPAS.pas" {Form1};

{$R *.res}

begin // здесь останавливаю, жму F7 и вываливается: Project  raised too many ...... и окно CPU
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end.


 
Drowsy   (2009-02-06 12:20) [32]

Может какие директивы компилятору нужны или опции линка???


 
Drowsy   (2009-02-06 12:22) [33]

В С++ билдере всё же идёт...


 
Сергей М. ©   (2009-02-06 12:22) [34]

А где текст юнита, в котором фигурирует Mess() ?


 
Drowsy   (2009-02-06 12:24) [35]

Drowsy   (06.02.09 09:14) [12]


 
Drowsy   (2009-02-06 12:26) [36]

Только stdcall добавил, но это ничего не изменило:
procedure Mess(); stdcall; external "MYDLL.dll" name "Mess";


 
Сергей М. ©   (2009-02-06 12:28) [37]

Для начала собери оба проекта без использования рантайм-пакетов, потом будем обсуждать


 
Ega23 ©   (2009-02-06 12:30) [38]

Почему stdcall? Где он явно указан в сишной части?
ЕМНИП, там по-умолчанию cdecl используется (хотя тоже не факт).

stdcall у тебя и в приложении должно фигурировать, и в библиотеке.


 
Drowsy   (2009-02-06 12:32) [39]

С готовностью.
Только я не понимаю, что значит "собери без рантаймов" -
убрать библиотеку с убогой функцией вообще?
Тогда кроме голой формы ничего не останется. :)


 
Сергей М. ©   (2009-02-06 12:33) [40]


> Ega23 ©   (06.02.09 12:30) [38]


В дан.случае фиолетово - до собственно вызова, судя по [31], дело не додит



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.11 c
3-1217238791
Fynjy
2008-07-28 13:53
2009.03.29
как вручную создать TIBDataBase


6-1201613360
Yurij-7
2008-01-29 16:29
2009.03.29
Отправка писем через Indy


6-1200923091
Maloj2007
2008-01-21 16:44
2009.03.29
Передача пакетов между IdTCPCllient и IdTCPServer


15-1233179940
Кое кто
2009-01-29 00:59
2009.03.29
Проверка языка...


1-1208548334
KIRILL_FR
2008-04-18 23:52
2009.03.29
Ошибка компилятора?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский