Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.03.29;
Скачать: CL | DM;

Вниз

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

 
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], дело не додит


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


> Drowsy   (06.02.09 12:32) [39]


Загляни в опции обоих проектов на закладку Pakages, там д.б. крыжик - сними его и там и здесь, после чего пересобери оба проекта и повтори трассировку


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

Ага, сейчас попробую.

(Кстати, может это о чём-то подскажет:
В окне CPU, при трассировке, ошибку вываливает при выполнении
ntdll.RTLunwind. )


 
Drowsy   (2009-02-06 12:42) [43]

... и ещё, если всё оставить, а убрать вызов Mess(), то работает.


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

Стек загажен


 
Drowsy   (2009-02-06 12:43) [45]

Наверное из-за too many consecutive exceptions


 
Drowsy   (2009-02-06 12:47) [46]

И с рантайм и без один и тот же эффект.


 
Сергей М. ©   (2009-02-06 14:38) [47]

Откажись на время от стат.загрузки, грузи библ-ку в динамике.
О результатах доложись.


 
Ega23 ©   (2009-02-06 14:43) [48]

О! Ещё одну штуку вспомнил.
Посмотри, в каком виде у тебя прописалась данная функция в DLL. Как-то раз наткнулись, что если какую-то сишную директиву не выставить, то к имени функции какой-то мусор добавляется, типа вместо "MyFunc" внутри dll сидит "MyFunc__%"


 
Drowsy   (2009-02-06 19:22) [49]


> Посмотри, в каком виде у тебя прописалась данная функция
> в DLL.

А как это сделать?


 
Ega23 ©   (2009-02-06 19:29) [50]


> А как это сделать?


Да тупо HEX-Editor"ом открой. Или блокнотом и имя функции найди.


 
Drowsy   (2009-02-06 20:09) [51]

В блокноте такой кусок встречается:
....  
 MyDll.dll @Mess$qv ___CPPdebugHook
.......



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

Текущий архив: 2009.03.29;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.021 c
2-1233414166
SkyN
2009-01-31 18:02
2009.03.29
получить содержимое и нажать кнопку страницы открытой в браузере


15-1232336012
Slider007
2009-01-19 06:33
2009.03.29
С днем рождения ! 18 января 2009 воскресенье


15-1231098857
Kerk
2009-01-04 22:54
2009.03.29
Реконкиста


15-1233208661
charoey_mag
2009-01-29 08:57
2009.03.29
GSM сигнализация по температуре


2-1233694291
mifi
2009-02-03 23:51
2009.03.29
инди сокет