Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как использовать dll откомпиленный для С в Delphi 
:(
    Опции темы
Гость_Frikazoid
Дата 7.10.2003, 22:05 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Доброго времени суток Господа!
Собственно сабж!
есть http://www.scancode.ru/download/10/Downl/71/
Мне надо те ф-ии в Delphi использовать!

Заранее спасибо за помощь!
  Вверх
Vit
Дата 7.10.2003, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207



ДЫк в чём проблема, все WINAPI на С написаны и импортируются без проблем...


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
var-alex
Дата 8.10.2003, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 7.10.2003
Где: Коломна, MCK

Репутация: 1
Всего: 1



Импотрируешь функции из него. Только описания надо верно перевести. И обязательно установить тип вызова stdcall для импортированных функций!
PM MAIL   Вверх
Dmitry V.Abramov
Дата 8.10.2003, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

Репутация: 5
Всего: 4



Цитата
http://www.scancode.ru/download/10/Downl/71/
Мне надо те ф-ии в Delphi использовать!

Если бы это было написано на C - подошел бы любой из предложенных тебе советов.
Если бы это было писано на BCB - пришлось бы подумать, но, скорее всего, тоже удалось бы подключить.
Но то, что у тебя там лежит, писано на VC++ с активным использованием MSVCRT.DLL и наружу торчат не функции, а классы и методы. В этом случае единственным вариантом видится написание на VC "посредника", преобразующего простые cdecl вызовы из Delphi в вызовы классов этой DLL.
--------------------
/DVA
PM MAIL WWW   Вверх
Dmitry V.Abramov
Дата 8.10.2003, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

Репутация: 5
Всего: 4



Цитата(Vit @ 7.10.2003, 23:10)
ДЫк в чём проблема, все WINAPI на С написаны и импортируются без проблем...

Именно на С и потому без проблем. В вопросе же фигурирует DLL писанная на C++ и экспортирующая класс и его методы.
--------------------
/DVA
PM MAIL WWW   Вверх
Гость_Frikazoid
Дата 8.10.2003, 17:11 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Не могли бы вы кинуть в меня чем ни будь откомпиленным или кусок кода? Я просто с С вааще никогда не работал!
  Вверх
var-alex
Дата 8.10.2003, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 7.10.2003
Где: Коломна, MCK

Репутация: 1
Всего: 1



Цитата(Dmitry @ 8.10.2003, 15:53)
Цитата(Vit @ 7.10.2003, 23:10)
ДЫк в чём проблема, все WINAPI на С написаны и импортируются без проблем...

Именно на С и потому без проблем. В вопросе же фигурирует DLL писанная на C++ и экспортирующая класс и его методы.

Прошу извинения. Я не смотрел туда... У меня инет не резиновый, кончается иногда sad.gif
PM MAIL   Вверх
Гость_Frikazoid
Дата 9.10.2003, 19:53 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Ну хоть что ни будь!
ПЛЗ!
  Вверх
Гость_Frikazoid
Дата 11.10.2003, 16:17 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Ну, Господа, может скажите что я должен сделать?
Плиз!
  Вверх
Dmitry V.Abramov
Дата 11.10.2003, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

Репутация: 5
Всего: 4



Цитата(Dmitry @ 8.10.2003, 15:41)
В этом случае единственным вариантом видится написание на VC "посредника", преобразующего простые cdecl вызовы из Delphi в вызовы классов этой DLL.

Разве не помогло? Что именно не получилось?
--------------------
/DVA
PM MAIL WWW   Вверх
Гость_Frikazoid
Дата 12.10.2003, 23:33 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата
...
Я просто с С вааще никогда не работал!

Вот это мешает!
  Вверх
stab
Дата 13.10.2003, 03:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 14
Всего: 48



сейчас я опишу свои соображения, которые, возможно, не совсем верны и не всегда будут работать smile.gif

Эксперименты будут проводиться с:
Код

class DLLCLASSES_API CDLLClass1 {
private:
int f1, f2;
public:
CDLLClass1(int p1, int p2);

~CDLLClass1();

void Inc(int p1, int p2);

int GetF(int which);
};


CDLLClass1::CDLLClass1(int p1, int p2)
{
f1 = p1;
f2 = p2;
}

CDLLClass1::~CDLLClass1()
{
Beep(1000, f1);
}

void CDLLClass1::Inc(int p1, int p2)
{
f1 += p1;
f2 += p2;
}

int CDLLClass1::GetF(int which)
{
switch(which)
{
case 1: return f1;
case 2: return f2;
default: return -1;
}
}


после того, как скомпиляли получили dll с такими функциями:

??0CDLLClass1@@QAE@HH@Z
??1CDLLClass1@@QAE@XZ
?GetF@CDLLClass1@@QAEHH@Z
?Inc@CDLLClass1@@QAEXHH@Z
??4CDLLClass1@@QAEAAV0@ABV0@@Z

если это перевести в удобоваримую форму, то получим:

CDLLClass1::CDLLClass1(int,int)
CDLLClass1::~CDLLClass1(void)
int CDLLClass1::GetF(int)
void CDLLClass1::Inc(int,int)
class CDLLClass1 & CDLLClass1::operator=(class CDLLClass1 const &)

Последнюю процедуру мы не определяли, ее добавил компилер. Судя по всему она осуществляет копирование экземпляров класса байт к байту.

Начнем с того, что попытаемся создать объект класса CDLLClass1. Объект в C++, так же как и в Delphi, просто область памяти, т.е. все что нам нужно это выделить нужное кол-во памяти и применить к ней конструктор. Если класс содержит виртуальные функции, то как-то надо еще помучиться с таблицой виртуальных функций, но мы обойдемся и без них. Размер объекта нашего класса 8 байт, т.к. два поля, каждое по 4 байта. Получаем:
Код

var
 obj: Pointer;
begin
 obj := AllocMem(8);
end;


Теперь надо вызвать конструктор. Все методы в C++, кроме методов с переменным числом параметров, используют thiscall соглашение о вызовах. thiscall -- это то же самое, что и stdcall только в ECX передается this (в Delphi-терминологии Self). Попытаемся это сделать:

Код

type
 TDLLClass1 = record
   f1, f2: Integer;
 end;
 PDLLClass1 = ^TDLLClass1;

function CDLLClass1_Create(p1: Integer; p2: Integer): Pointer; stdcall; external 'dllclasses.dll' name '??0CDLLClass1@@QAE@HH@Z';

procedure TForm1.Button1Click(Sender: TObject);
var
 obj: PDLLClass1;
begin
 obj := AllocMem(8);

 asm
   mov   ECX, [obj]
 end;

 CDLLClass1_Create(1, 2);

 ShowMessage(IntToStr(obj.f1));
end;


Теперь вызовем методы Inc и GetF:
Код

function CDLLClass1_Create(p1: Integer; p2: Integer): Pointer; stdcall; external 'dllclasses.dll' name '??0CDLLClass1@@QAE@HH@Z';
procedure CDLLClass1_Inc(p1: Integer; p2: Integer); stdcall; external 'dllclasses.dll' name '?Inc@CDLLClass1@@QAEXHH@Z';
function CDLLClass1_GetF(which: Integer): Integer; stdcall; external 'dllclasses.dll' name '?GetF@CDLLClass1@@QAEHH@Z';

procedure TForm1.Button1Click(Sender: TObject);
var
 obj: Pointer;
begin
 obj := AllocMem(8);

 asm
   mov   ECX, [obj]
 end;
 CDLLClass1_Create(1, 2);

 asm
   mov   ECX, [obj]
 end;
 CDLLClass1_Inc(1, 2);

 asm
   mov   ECX, [obj]
 end;
 ShowMessage(IntToStr(CDLLClass1_GetF(2)));
end;

Я снова объявил obj как Pointer, для того, чтобы показать ненужность знаний о внутренней структуре объекта. И на конец вызовем деструктор и освободим память.

Код

function CDLLClass1_Create(p1: Integer; p2: Integer): Pointer; stdcall; external 'dllclasses.dll' name '??0CDLLClass1@@QAE@HH@Z';
procedure CDLLClass1_Inc(p1: Integer; p2: Integer); stdcall; external 'dllclasses.dll' name '?Inc@CDLLClass1@@QAEXHH@Z';
function CDLLClass1_GetF(which: Integer): Integer; stdcall; external 'dllclasses.dll' name '?GetF@CDLLClass1@@QAEHH@Z';
procedure CDLLClass1_Destroy; stdcall; external 'dllclasses.dll' name '??1CDLLClass1@@QAE@XZ';

procedure TForm1.Button1Click(Sender: TObject);
var
 obj: Pointer;
begin
 obj := AllocMem(8);

 asm
   mov   ECX, [obj]
 end;
 CDLLClass1_Create(1, 2);

 asm
   mov   ECX, [obj]
 end;
 CDLLClass1_Inc(5000, 2);

 asm
   mov   ECX, [obj]
 end;
 ShowMessage(IntToStr(CDLLClass1_GetF(2)));

 asm
   mov   ECX, [obj]
 end;
 CDLLClass1_Destroy;

 FreeMem(obj, 8);
end;



--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
stab
Дата 13.10.2003, 03:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 14
Всего: 48



теперь о вопросе этого топика smile.gif

список функций:

??0CCipher@@QAE@XZ
??4CCipher@@QAEAAV0@ABV0@@Z
?CheckComm@CCipher@@QAEHXZ
?ClearDatabase@CCipher@@QAEHH@Z
?CloseComm@CCipher@@QAEXXZ
?Finish@CCipher@@QAEHXZ
?GetCurrentState@CCipher@@QAEHPAD@Z
?GetDataCount@CCipher@@QAEJH@Z
?GetFreeMemory@CCipher@@QAEJXZ
?GetLastError@CCipher@@QAEHPAD@Z
?GetSerialNumber@CCipher@@QAEHPAD@Z
?GetTime@CCipher@@QAEHPAD@Z
?InitComm@CCipher@@AAEHXZ
?OpenComm@CCipher@@QAEHH@Z
?OpenComm@CCipher@@QAEHHH@Z
?OpenComm@CCipher@@QAEHHHH@Z
?OpenIrDA@CCipher@@AAEHXZ
?Ping@CCipher@@QAEHXZ
?PutRecord@CCipher@@QAEHHPBD@Z
?ReadRecord@CCipher@@QAEHHPAD@Z
?SendCommand@CCipher@@AAEHPBDPAD@Z
?SendData@CCipher@@AAEHPBD@Z
?TestIrDA@CCipher@@AAEHK@Z
?TimeDly@CCipher@@AAEXXZ
?UpdateTime@CCipher@@QAEHXZ

CCipher::CCipher(void)
class CCipher & CCipher::operator=(class CCipher const &)
int CCipher::CheckComm(void)
int CCipher::ClearDatabase(int)
void CCipher::CloseComm(void)
int CCipher::Finish(void)
int CCipher::GetCurrentState(char *)
long CCipher::GetDataCount(int)
long CCipher::GetFreeMemory(void)
int CCipher::GetLastError(char *)
int CCipher::GetSerialNumber(char *)
int CCipher::GetTime(char *)
int CCipher::InitComm(void)
int CCipher::OpenComm(int)
int CCipher::OpenComm(int,int)
int CCipher::OpenComm(int,int,int)
int CCipher::OpenIrDA(void)
int CCipher::Ping(void)
int CCipher::PutRecord(int,char const *)
int CCipher::ReadRecord(int,char *)
int CCipher::SendCommand(char const *,char *)
int CCipher::SendData(char const *)
int CCipher::TestIrDA(unsigned long)
void CCipher::TimeDly(void)
int CCipher::UpdateTime(void)

проблем быть, вроде, не должно ;) самое сложное определить размер объекта, тут два варианта:

1. В VC написать sizeof(CCipher) и посмотреть чему это равно.
2. Взять заведомо достаточный объем памяти.

Вариант 1 конечно лучше.

Frikazoid, если будут проблемы с конвертацией функций в delphi -- пиши, ну и вообще если будут проблемы -- пиши smile.gif


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
stab
Дата 13.10.2003, 04:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 14
Всего: 48



хм, sizeof(CCipher) = 1 smile.gif чего-то я не понимаю как пользоваться этой библиотекой в VC.

Код

CCipher * c = new CCipher();
c->CheckComm();

приводит к "Unhandled exception at 0x10001100 (Cipher.dll) in app.exe: 0xC0000005: Access violation reading location 0x00000020."
Обращение к любому методу приводит к эксепшенам. Похоже sizeof(CCipher) != 1 smile.gif


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Dmitry V.Abramov
Дата 13.10.2003, 07:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

Репутация: 5
Всего: 4



Цитата(cully @ 13.10.2003, 04:22)
Похоже sizeof(CCipher) != 1 :)

Хочется выказать уважение к проделанной работе, и оказать посильную помощь. Судя по коду оператора копирования
Код
; public: class CCipher & __thiscall CCipher::operator=(class CCipher const &)

??4CCipher@@QAEAAV0@ABV0@@Z proc near

arg_0           = dword ptr  8

               push    esi
               mov     esi, [esp+arg_0]
               mov     eax, ecx
               push    edi
               mov     ecx, 10h
               mov     edi, eax
               repe movsd
               pop     edi
               pop     esi
               retn    4
??4CCipher@@QAEAAV0@ABV0@@Z endp

... величина этого Cipher'a равна $10*4=64 байта.
--------------------
/DVA
PM MAIL WWW   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1133 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.