Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Akylax
15 / 0 / 0
Регистрация: 27.11.2012
Сообщений: 93
16.10.2013, 14:40     Написание dll - библиотеки и ее открытие средствами Delphi #1
Есть некоторая 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++?
Или может кто знает другие пути решения?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.10.2013, 14:40     Написание dll - библиотеки и ее открытие средствами Delphi
Посмотрите здесь:

C++ Работа со звуком средствами библиотеки мультимедиа Windows
C++ Написание библиотеки
Подключение dll библиотеки C++
C++ Написание библиотеки для воспроизведения MP3
C++ Компиляция dll библиотеки
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
palva
 Аватар для palva
2372 / 1594 / 190
Регистрация: 08.06.2007
Сообщений: 6,362
Записей в блоге: 4
16.10.2013, 15:41     Написание dll - библиотеки и ее открытие средствами Delphi #2
Чтобы проиндексировать, нужно подключить к проекту Visual Studio def-файл, где описываются все экспорты библиотеки с именами и индексами.

Добавлено через 42 минуты
Код
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
palva
 Аватар для palva
2372 / 1594 / 190
Регистрация: 08.06.2007
Сообщений: 6,362
Записей в блоге: 4
16.10.2013, 15:47     Написание dll - библиотеки и ее открытие средствами Delphi #3
файл dll
Вложения
Тип файла: zip simpledll.dll.zip (7.8 Кб, 4 просмотров)
Akylax
15 / 0 / 0
Регистрация: 27.11.2012
Сообщений: 93
16.10.2013, 20:59  [ТС]     Написание dll - библиотеки и ее открытие средствами Delphi #4
Цитата Сообщение от palva Посмотреть сообщение
simple.def
LIBRARY "simpledll"
EXPORTS
Square @1
Perimeter @2
Теперь он не может получить ссылки на функции, если переписать код.
Цитата Сообщение от palva Посмотреть сообщение
файл dll
Скачивал ваш, там даже библиотеку загрузить не может. У меня подозрение, а среда вообще учитывает этот Def-файл?
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,042
16.10.2013, 21:13     Написание dll - библиотеки и ее открытие средствами Delphi #5
Akylax,
Мне конечно лень разбираться , но так на вскидку я не увидел слов(ключевых) extern "C"
все дело в том что без них в библиотеке не будет функции Square а будет какая то Square@d2..ну и так далее
можно проверить например PE Explorer
язык С++кодирует в имени функции все параметры этой функции( причем каждый компилятор по своему)
и если бы ты писал на Булдере то Делфи бы тебя понял(как никак одна фирма) но ты пишешь на Визуале( там своя кодировка) посему и нужно включать эти волшебные слова(extern "C") тогда и будет твоя функция иметь вид Square
правда параметры на твоей совести,если не правильно отдашь.то одному Биллу известо, что будет
Akylax
15 / 0 / 0
Регистрация: 27.11.2012
Сообщений: 93
16.10.2013, 21:18  [ТС]     Написание dll - библиотеки и ее открытие средствами Delphi #6
Цитата Сообщение от ValeryS Посмотреть сообщение
язык С++кодирует в имени функции все параметры этой функции( причем каждый компилятор по своему)
и если бы ты писал на Булдере то Делфи бы тебя понял(как никак одна фирма) но ты пишешь на Визуале( там своя кодировка)
Этого я и боялся.
Цитата Сообщение от ValeryS Посмотреть сообщение
я не увидел слов(ключевых) extern "C"
все дело в том что без них в библиотеке не будет функции Square а будет какая то Square@d2
А куда ставить то? в .cpp? не канает.
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,042
16.10.2013, 21:32     Написание dll - библиотеки и ее открытие средствами Delphi #7
Цитата Сообщение от 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-ru/library/0603949d.aspx
а вообще почитай что такое искажение имен
простой пример
C++
1
2
int max(int a,int b)
char max(char a, char b)
в Си даст ошибку компиляции, а в плюсах нет
почему ?
все очень просто плюсы в имя функции забивают количество и тип параметров, причем каждая фирма по своему

Добавлено через 2 минуты
Akylax,
скачай себе PE Explorer(до 30 дней он бесплатен)
и скорми ему две ДЛЛки с extern "C" и без
и увидишь разницу в именах функций
palva
 Аватар для palva
2372 / 1594 / 190
Регистрация: 08.06.2007
Сообщений: 6,362
Записей в блоге: 4
16.10.2013, 21:45     Написание dll - библиотеки и ее открытие средствами Delphi #8
Цитата Сообщение от Akylax Посмотреть сообщение
А куда ставить то? в .cpp? не канает.
У меня показано, куда.
Откровенно говоря, я не понял ваши трудности. Вот эту фразу:
Цитата Сообщение от Akylax Посмотреть сообщение
Теперь он не может получить ссылки на функции, если переписать код.
Что вы пытаетесь сделать и что происходит?
Цитата Сообщение от Akylax Посмотреть сообщение
Скачивал ваш, там даже библиотеку загрузить не может.
Где там?

Добавлено через 12 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
скачай себе PE Explorer(до 30 дней он бесплатен)
Вы что, не можете посмотреть экспорты dll ? Вы же в Delphi работаете. У вас есть утилита tdump. Вот вырезаю из листинга из ее выдачи:
Код
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 секунд
Видны внешние имена и индексы. Можете загружать по именам, можете по индексам.
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,042
16.10.2013, 21:54     Написание dll - библиотеки и ее открытие средствами Delphi #9

Не по теме:

Цитата Сообщение от 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
palva
 Аватар для palva
2372 / 1594 / 190
Регистрация: 08.06.2007
Сообщений: 6,362
Записей в блоге: 4
16.10.2013, 22:12     Написание dll - библиотеки и ее открытие средствами Delphi #10
Вот работающая программа 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,
ValeryS
16.10.2013, 22:45
  #11

Не по теме:

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

Akylax
15 / 0 / 0
Регистрация: 27.11.2012
Сообщений: 93
16.10.2013, 22:54  [ТС]     Написание dll - библиотеки и ее открытие средствами Delphi #12
Цитата Сообщение от palva Посмотреть сообщение
Вот работающая программа Delphi
У меня она и так работает, я не это спрашивал
Цитата Сообщение от ValeryS Посмотреть сообщение
вот кстати для ТС еще несколько ссылок
Википедия то зачем
Цитата Сообщение от palva Посмотреть сообщение
PE Explorer
Он не решит проблему
Цитата Сообщение от palva Посмотреть сообщение
Скачивал ваш, там даже библиотеку загрузить не может.
Где там?
Вы загрузили на сайт архив с ддлкой, я и ее пробнул. Вот такой результат получил.
Цитата Сообщение от palva Посмотреть сообщение
У вас есть утилита tdump. Вот вырезаю из листинга из ее выдачи:
Господи, что за ужас!
Цитата Сообщение от palva Посмотреть сообщение
Можете загружать по именам
В статичном методе пробовал по именам грузить(еще старая версия dll-ки была) ругался на недоступность к точкам доступа процедуры
Цитата Сообщение от ValeryS Посмотреть сообщение
extern "C" double dllclass::Square(double n, double b)
попробую
palva
 Аватар для palva
2372 / 1594 / 190
Регистрация: 08.06.2007
Сообщений: 6,362
Записей в блоге: 4
16.10.2013, 23:03     Написание dll - библиотеки и ее открытие средствами Delphi #13
Цитата Сообщение от Akylax Посмотреть сообщение
У меня она и так работает, я не это спрашивал
Вы сказали, что у вас моя dll не грузится. У меня грузится и выполняется. Это работающий пример.
Цитата Сообщение от Akylax Посмотреть сообщение
В статичном методе пробовал по именам грузить(еще старая версия dll-ки была) ругался на недоступность к точкам доступа процедуры
Тот же вопрос: неужели вы не могли посмотреть имя экспорта и указать правильное имя? Откройте dll в текстовом редакторе, наконец, и поищите имя.
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,042
16.10.2013, 23:05     Написание dll - библиотеки и ее открытие средствами Delphi #14
Цитата Сообщение от Akylax Посмотреть сообщение
Википедия то зачем
это ты про wikibooks?
ну чтобы знал что есть экспорт что есть импорт
информация нужно брать отовсюду(правда критично к ней относится)
Цитата Сообщение от Akylax Посмотреть сообщение
Он не решит проблему
конечно не решит
но покажет, что экспортирует твоя ДЛЛка
Цитата Сообщение от Akylax Посмотреть сообщение
class dllclass
не заметил сначала
забудь в ДЛЛках про классы, это дело тонкое( тоже искажение имен) поройся в инете про классы в ДЛЛках и поймешь что чаше всего они не нужны, но если так хочется то полностью переписывай интерфейс
ибо трудно левой программе создать объект класса
посмотри как реализован DirectX
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,572
Записей в блоге: 17
16.10.2013, 23:17     Написание dll - библиотеки и ее открытие средствами Delphi #15
Цитата Сообщение от ValeryS Посмотреть сообщение
забудь в ДЛЛках про классы
Да ибо "форматы" в Delphi и VC++ разные для классов.

Можно попробовать писать в Delphi/С++Builder там должно работать.
Akylax
15 / 0 / 0
Регистрация: 27.11.2012
Сообщений: 93
20.10.2013, 20:55  [ТС]     Написание dll - библиотеки и ее открытие средствами Delphi #16
Цитата Сообщение от palva Посмотреть сообщение
Это работающий пример.
А это рабочая программа. Все дело в различии компилирующей IDE
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.10.2013, 21:51     Написание dll - библиотеки и ее открытие средствами Delphi
Еще ссылки по теме:

C++ Написание и использование DLL
открытие и считывание из .dll C++
Написание библиотеки в С++ для вызова в C# C++

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

Или воспользуйтесь поиском по форуму:
palva
 Аватар для palva
2372 / 1594 / 190
Регистрация: 08.06.2007
Сообщений: 6,362
Записей в блоге: 4
20.10.2013, 21:51     Написание dll - библиотеки и ее открытие средствами Delphi #17
Цитата Сообщение от Akylax Посмотреть сообщение
Все дело в различии компилирующей IDE
Сомневаюсь. Откуда вы взяли, что я пользовался IDE при компиляции программы Делфи?
Может зависеть от версии Delphi. Например, если у вас 16-разрядная Delphi-1, то она изготовит exe-файл, которая не сможет загрузить мою dll, поскольку dll 32-разрядная. Но изготовить 16-разрядную dll при помощи современной Microsoft VS вы не сможете в любом случае.
Yandex
Объявления
20.10.2013, 21:51     Написание dll - библиотеки и ее открытие средствами Delphi
Ответ Создать тему
Опции темы

Текущее время: 12:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru