Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
15 / 0 / 2
Регистрация: 27.11.2012
Сообщений: 93

Написание dll - библиотеки и ее открытие средствами Delphi

16.10.2013, 14:40. Показов 2699. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть некоторая dll-библиотека, которая вычисляет площадь и периметр n-угольника. Лабораторная была на Delphi, решил попробовать написать dll-ку средствами языка C++ (на Visual Studio)
На msdn, нашел алгоритм написания:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//Simple.h
namespace dllspace{
    #define M_PI 3.1415926535897932384626433832795
    class dllclass
    {
    public:
        static __declspec(dllexport) double Square(double n, double b);
            
    public:
        static __declspec(dllexport) double Perimeter(double n, double b);
    };
}
//SimpleCPP.cpp
#include <math.h>
#include <stdexcept>
#include "SimpleH.h"
namespace dllspace
    {
     double dllclass::Square(double n, double b)
            {
             return( (1/4)*n*b*b*(1/tan(M_PI/n)));
            } 
    double dllclass::Perimeter(double n, double b)
        {
        return (n*b);
        }
    }
Открываю в приложении, которое динамически(т.е. в процессе выполнения) загружает dll-ку. Приложение 100% работает, если использовать dll-ку собранную в delphi.
P.S. Использовал соглашение cdecl
Кликните здесь для просмотра всего текста

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Polygon.dll
library Polygon;
 
uses
  SysUtils,
  Classes,
  Math;
 
{$R *.res}
 
Function sq_polygon(n,b:Real):Real; stdcall;
begin
Result:=(1/4)*n*b*b*Cotan(Pi/n);
end;
Function perimeter_polygon(n,b:Real):Real; stdcall;
begin
Result:=n*b;
end;
 
Exports
 sq_polygon index 1, perimeter_polygon index 2;
begin
end.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//App_polygon.pas
unit App_polygon;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    valve: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
   //CONST DLLName='Polygon.dll'; // имя DLL
   CONST DLLName='SimpleDLL.dll'; // имя DLL
  Type
  TAllFunc = Function(n,b:Real):Real; cdecl;//stdcall;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
Var
  n,b:Real;
  Square:TAllFunc;
  Perimeter:TAllFunc;
  flag:Boolean;
  Handle:LongInt;
begin
  flag:=false;
  if( Edit1.Text <> '') then
  b:=StrToFloat(Edit1.Text)
  else
    ShowMessage('Введите параметр b!');
  if( Edit2.Text <> '')  then
    begin
    n:=StrToFloat(Edit2.Text);
    flag:=true;
    end
  else
    ShowMessage('Введите параметр n!');
  if(flag=true) then
  begin
     //Загружаем библиотеку
      Handle:=LoadLibrary(DLLName);
      if(Handle<>0) then
      begin
      @Square := GetProcAddress(Handle,PChar(LongInt(1)));
      @Perimeter := GetProcAddress(Handle,PChar(LongInt(2)));
 
     IF Assigned(Square) then
  Label5.Caption:=FloatToStrF(Square(n,b),ffFixed,10,4)
                   else
                   ShowMessage('Ошибка доступа к библиотеке(Sq) '+DLLName);
    IF Assigned(Perimeter) then
  Label6.Caption:=FloatToStrF(Perimeter(n,b),ffFixed,10,4)
                            else
                           ShowMessage('Ошибка доступа к библиотеке(Per) '+DLLName);
      end //Handle <>0
      else ShowMessage('Ошибка загрузки библиотеки'+DLLName);
   FreeLibrary(handle);
  end;//flag=true
 
end;
 
end.

А если использовать эту, происходит странное. Она полностью пропускает функцию Square, и вызывает функцию Perimeter, причем записывает ф-ю Perimeter в первую переменную, которая хранит ссылку на функцию из dll - библиотеки. Вторая такая переменная содержит результат 0.0.
Как можно проиндексировать функции в dll-ке, написанной на c++?
Или может кто знает другие пути решения?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.10.2013, 14:40
Ответы с готовыми решениями:

открытие БД из dll-библиотеки
Народ, подскажите плз как засунуть аксесовскую БД в длл-библиотеку (если это вообще возможно), и как потом подгрузить её в программу через...

Работа с SATA портами средствами библиотеки PortIO32.dll
во-первых хочу отметить, что поиск в интернете толковой информации по данному вопросу не увенчались успехом (везде только про COM порт),...

Открытие документа Word средствами Delphi
Подскажите, как открыть в окне Delphi документ с расширением *.doc ??? Чтобы отображались все формулы, диаграммы и рисунки???? Что для...

16
 Аватар для palva
4278 / 2970 / 693
Регистрация: 08.06.2007
Сообщений: 9,930
Записей в блоге: 5
16.10.2013, 15:41
Чтобы проиндексировать, нужно подключить к проекту Visual Studio def-файл, где описываются все экспорты библиотеки с именами и индексами.

Добавлено через 42 минуты
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
simple.h
#define M_PI 3.1415926535897932384626433832795
extern "C" {
double Square(double, double);
double Perimeter(double, double);
}
 
simple.cpp
#include <math.h>
#include "simple.h"
 
double Square(double n, double b)
{
    return( (1/4)*n*b*b*(1/tan(M_PI/n)));
} 
double Perimeter(double n, double b)
{
    return (n*b);
}
 
simple.def
LIBRARY "simpledll"
EXPORTS
Square @1
Perimeter @2
0
 Аватар для palva
4278 / 2970 / 693
Регистрация: 08.06.2007
Сообщений: 9,930
Записей в блоге: 5
16.10.2013, 15:47
файл dll
Вложения
Тип файла: zip simpledll.dll.zip (7.8 Кб, 8 просмотров)
0
15 / 0 / 2
Регистрация: 27.11.2012
Сообщений: 93
16.10.2013, 20:59  [ТС]
Цитата Сообщение от palva Посмотреть сообщение
simple.def
LIBRARY "simpledll"
EXPORTS
Square @1
Perimeter @2
Теперь он не может получить ссылки на функции, если переписать код.
Цитата Сообщение от palva Посмотреть сообщение
файл dll
Скачивал ваш, там даже библиотеку загрузить не может. У меня подозрение, а среда вообще учитывает этот Def-файл?
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
16.10.2013, 21:13
Akylax,
Мне конечно лень разбираться , но так на вскидку я не увидел слов(ключевых) extern "C"
все дело в том что без них в библиотеке не будет функции Square а будет какая то Square@d2..ну и так далее
можно проверить например PE Explorer
язык С++кодирует в имени функции все параметры этой функции( причем каждый компилятор по своему)
и если бы ты писал на Булдере то Делфи бы тебя понял(как никак одна фирма) но ты пишешь на Визуале( там своя кодировка) посему и нужно включать эти волшебные слова(extern "C") тогда и будет твоя функция иметь вид Square
правда параметры на твоей совести,если не правильно отдашь.то одному Биллу известо, что будет
0
15 / 0 / 2
Регистрация: 27.11.2012
Сообщений: 93
16.10.2013, 21:18  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
язык С++кодирует в имени функции все параметры этой функции( причем каждый компилятор по своему)
и если бы ты писал на Булдере то Делфи бы тебя понял(как никак одна фирма) но ты пишешь на Визуале( там своя кодировка)
Этого я и боялся.
Цитата Сообщение от ValeryS Посмотреть сообщение
я не увидел слов(ключевых) extern "C"
все дело в том что без них в библиотеке не будет функции Square а будет какая то Square@d2
А куда ставить то? в .cpp? не канает.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
16.10.2013, 21:32
Цитата Сообщение от Akylax Посмотреть сообщение
А куда ставить то? в .cpp? не канает.
ну не знаю
примерно так
Цитата Сообщение от Akylax Посмотреть сообщение
double dllclass::Square(double n, double b)
C++
1
extern "C" double dllclass::Square(double n, double b)
вот тебе пара ссылок про эту фигню
extern
http://msdn.microsoft.com/ru-r... 3949d.aspx
а вообще почитай что такое искажение имен
простой пример
C++
1
2
int max(int a,int b)
char max(char a, char b)
в Си даст ошибку компиляции, а в плюсах нет
почему ?
все очень просто плюсы в имя функции забивают количество и тип параметров, причем каждая фирма по своему

Добавлено через 2 минуты
Akylax,
скачай себе PE Explorer(до 30 дней он бесплатен)
и скорми ему две ДЛЛки с extern "C" и без
и увидишь разницу в именах функций
0
 Аватар для palva
4278 / 2970 / 693
Регистрация: 08.06.2007
Сообщений: 9,930
Записей в блоге: 5
16.10.2013, 21:45
Цитата Сообщение от Akylax Посмотреть сообщение
А куда ставить то? в .cpp? не канает.
У меня показано, куда.
Откровенно говоря, я не понял ваши трудности. Вот эту фразу:
Цитата Сообщение от Akylax Посмотреть сообщение
Теперь он не может получить ссылки на функции, если переписать код.
Что вы пытаетесь сделать и что происходит?
Цитата Сообщение от Akylax Посмотреть сообщение
Скачивал ваш, там даже библиотеку загрузить не может.
Где там?

Добавлено через 12 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
скачай себе PE Explorer(до 30 дней он бесплатен)
Вы что, не можете посмотреть экспорты dll ? Вы же в Delphi работаете. У вас есть утилита tdump. Вот вырезаю из листинга из ее выдачи:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Section:             Exports
File Offset:         00003A00 (14848)
  Flags:             00000000
  Time Stamp:        525E7AC7 : Wed Oct 16 15:38:47 2013
  Major Version:     0000
  Minor Version:     0000
 
Exports from simpledll.dll
  2 exported name(s), 2 export addresse(s).  Ordinal base is 1.
  Sorted by Name:
    RVA      Ord. Hint Name
    -------- ---- ---- ----
    000110D2    2 0000 Perimeter
    00011050    1 0001 Square
Добавлено через 50 секунд
Видны внешние имена и индексы. Можете загружать по именам, можете по индексам.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
16.10.2013, 21:54

Не по теме:

Цитата Сообщение от palva Посмотреть сообщение
Вы что, не можете посмотреть экспорты dll ? Вы же в Delphi работаете.
и в вижуале есть эта приблуда
просто я PE Explorer порекомендовал, он более нагляден
закачал в него ДЛЛку или ЕХЕшку а он покажет и импорт и экспорт и отложенный импорт и по именам и по номерам


вот кстати для ТС еще несколько ссылок
http://www.codenet.ru/progr/bcb/dll.php
http://ru.wikibooks.org/wiki/DLL
http://www.rsdn.ru/article/baseserv/dlluse.xml
0
 Аватар для palva
4278 / 2970 / 693
Регистрация: 08.06.2007
Сообщений: 9,930
Записей в блоге: 5
16.10.2013, 22:12
Вот работающая программа Delphi
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{$APPTYPE CONSOLE}
program pg88;
uses Windows;
Type
    TAllFunc = Function(n,b:Real):Real; cdecl;//stdcall;
var
    Handle:HModule;
    Square, Perimeter: TAllFunc;
    n,b: Real;
begin
    Handle:=LoadLibrary('simpledll.dll');
    if(Handle<>0) then
    begin
        @Square := GetProcAddress(Handle,PChar(LongInt(1)));
        @Perimeter := GetProcAddress(Handle,PChar(LongInt(2)));
        n := 3.0;
        b := 4.0;
        WriteLn(Perimeter(n,b));
    end;
end.
Square возвращает нуль, поскольку вы неправильно реализовали ее на си.
C++
1
1/4
Это выражение дает нуль. Надо писать
C++
1
1.0/4.0
Добавлено через 2 минуты
Цитата Сообщение от palva Посмотреть сообщение
Вы что, не можете посмотреть экспорты dll ?
ValeryS, Извините, это я обращался к Akylax,
1
16.10.2013, 22:45

Не по теме:

Цитата Сообщение от palva Посмотреть сообщение
ValeryS, Извините, это я обращался к Akylax,
да не, нормально:)
у каждой более менее серьезной ИДЕшки есть прога чтобы прочитать импорт экспорт
но иногда сторонние более удобны

0
15 / 0 / 2
Регистрация: 27.11.2012
Сообщений: 93
16.10.2013, 22:54  [ТС]
Цитата Сообщение от palva Посмотреть сообщение
Вот работающая программа Delphi
У меня она и так работает, я не это спрашивал
Цитата Сообщение от ValeryS Посмотреть сообщение
вот кстати для ТС еще несколько ссылок
Википедия то зачем
Цитата Сообщение от palva Посмотреть сообщение
PE Explorer
Он не решит проблему
Цитата Сообщение от palva Посмотреть сообщение
Скачивал ваш, там даже библиотеку загрузить не может.
Где там?
Вы загрузили на сайт архив с ддлкой, я и ее пробнул. Вот такой результат получил.
Цитата Сообщение от palva Посмотреть сообщение
У вас есть утилита tdump. Вот вырезаю из листинга из ее выдачи:
Господи, что за ужас!
Цитата Сообщение от palva Посмотреть сообщение
Можете загружать по именам
В статичном методе пробовал по именам грузить(еще старая версия dll-ки была) ругался на недоступность к точкам доступа процедуры
Цитата Сообщение от ValeryS Посмотреть сообщение
extern "C" double dllclass::Square(double n, double b)
попробую
0
 Аватар для palva
4278 / 2970 / 693
Регистрация: 08.06.2007
Сообщений: 9,930
Записей в блоге: 5
16.10.2013, 23:03
Цитата Сообщение от Akylax Посмотреть сообщение
У меня она и так работает, я не это спрашивал
Вы сказали, что у вас моя dll не грузится. У меня грузится и выполняется. Это работающий пример.
Цитата Сообщение от Akylax Посмотреть сообщение
В статичном методе пробовал по именам грузить(еще старая версия dll-ки была) ругался на недоступность к точкам доступа процедуры
Тот же вопрос: неужели вы не могли посмотреть имя экспорта и указать правильное имя? Откройте dll в текстовом редакторе, наконец, и поищите имя.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
16.10.2013, 23:05
Цитата Сообщение от Akylax Посмотреть сообщение
Википедия то зачем
это ты про wikibooks?
ну чтобы знал что есть экспорт что есть импорт
информация нужно брать отовсюду(правда критично к ней относится)
Цитата Сообщение от Akylax Посмотреть сообщение
Он не решит проблему
конечно не решит
но покажет, что экспортирует твоя ДЛЛка
Цитата Сообщение от Akylax Посмотреть сообщение
class dllclass
не заметил сначала
забудь в ДЛЛках про классы, это дело тонкое( тоже искажение имен) поройся в инете про классы в ДЛЛках и поймешь что чаше всего они не нужны, но если так хочется то полностью переписывай интерфейс
ибо трудно левой программе создать объект класса
посмотри как реализован DirectX
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.10.2013, 23:17
Цитата Сообщение от ValeryS Посмотреть сообщение
забудь в ДЛЛках про классы
Да ибо "форматы" в Delphi и VC++ разные для классов.

Можно попробовать писать в Delphi/С++Builder там должно работать.
0
15 / 0 / 2
Регистрация: 27.11.2012
Сообщений: 93
20.10.2013, 20:55  [ТС]
Цитата Сообщение от palva Посмотреть сообщение
Это работающий пример.
А это рабочая программа. Все дело в различии компилирующей IDE
0
 Аватар для palva
4278 / 2970 / 693
Регистрация: 08.06.2007
Сообщений: 9,930
Записей в блоге: 5
20.10.2013, 21:51
Цитата Сообщение от Akylax Посмотреть сообщение
Все дело в различии компилирующей IDE
Сомневаюсь. Откуда вы взяли, что я пользовался IDE при компиляции программы Делфи?
Может зависеть от версии Delphi. Например, если у вас 16-разрядная Delphi-1, то она изготовит exe-файл, которая не сможет загрузить мою dll, поскольку dll 32-разрядная. Но изготовить 16-разрядную dll при помощи современной Microsoft VS вы не сможете в любом случае.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.10.2013, 21:51
Помогаю со студенческими работами здесь

Подключение библиотеки (DLL) на Delphi к проекту на C#
Добрый день. Создал длл на Delphi XE2 library Lic; uses System.SysUtils, System.Classes; {$R *.res}

Как указатели из библиотеки dll на с++ использовать в delphi
Добрый день. Вопрос состоит в следующем, у меня есть библиотека на c++, из которой нужно утащить некоторые функции. Пример функции,...

Создание dll библиотеки в C#. Вызов классов этой библиотеки
мне нужно как то создать динамическую библиотеку класов в си шарп, основой этой библиотеки должен быть абстрактный класс, от которого будут...

Как использовать методы библиотеки DLL, и игнорировать их, когда DLL нету?
Как использовать методы библиотеки DLL , и игнорировать их когда DLL нету Что нужно , мне нужно так чтоб проверялось наличие библиотеки ...

Где взять библиотеки JSCore.dll и WebKitCore.dll
Доброго времени суток. Скачал ExpressoBrowser-master, пытаюсь запустить через SharpDevelop 4.4, выскакивает ошибка, дескать нет JSCore.dll...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru