Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обращение из Delphi к DLL написанной на C++ [D7, WinXP]


Страницы:   1 2 3

smirnoff ©   (2009-07-03 12:02:00) 

Здравствуйте! У меня вопрос по работе с типом puchar. Такая ситуация: имеется dll файл написанный на C++Builder. Из dll экспортируется функция следующим образом

extern "C" bool __declspec( dllexport ) func1(unsigned char *input, unsigned char *output);

В проекте Delphi импортируем эту функцию:

function func1(input: pointer; output: pointer): bool; cdecl;
external 'my.dll' name '_func1';


Работаем с импортированной функцией func1:

procedure TForm1.Button1Click(Sender: TObject);
var
 i :integer;
 s : string;
 a: array[0..30000] of char;
 b: ^uchar;

 a2: array[0..60000] of uchar;
 b2: ^uchar;
begin
StrCopy(a, pchar(Memo1.Text));

b := @a;
b2 := @a2;

func1(b,b2);

for I := 0 to Length(Memo1.Text) do
s := s + chr(a2[i]);
Memo2.Text := s;
end;


Проблемав том, что func1 видит только первый (нулевой) символ массива "a", а необходимо, чтобы весь массив был доступен для dll.

Вот в dll выводится на экран параметр input
ShowMessage((char *)input);

Объясните, пожалуйста, как правильно передать указатель на uchar из Delphi в dll. Заранее огромное спасибо!


KSergey   (2009-07-10 10:44:00) [21]

Меня вот это смущает в объявлениях:

> extern "C" bool__declspec( dllexport ) func1(unsigned char *input, unsigned char *output);
>
> function func1(input: pointer; output: pointer): bool; cdecl;

bool в дельфи и bool в C++ - сильно очень разное.
Надо в С++ написать BOOL (именно капслоком), тогда все будет хорошо (для порядку я и в дельфи капслоком пишу, хотя там это не важно, регистронечувствительный язык).

Хотя, понятно, проблемы с массивом это не решит, но может "неожидано" вылезти при анализе результата.


KSergey   (2009-07-10 10:39:00) [22]

> smirnoff ©   (06.07.09 19:51) [21]
> я бы поставил галочки win7 и d2009, если бы они были доступны

Правильно, поэтому поставил галочки не соответствующие действительности. Зашибись подход!!!


Сергей М.   (2009-07-06 20:01:00) [23]


> администрация не заботиться о том, что выходят новые версии
> ОС и RAD-ов


Проблемы индейцев - это проблемы индейцев... Шерифа они не волнуют.


smirnoff   (2009-07-06 19:51:00) [24]

я бы поставил галочки win7 и d2009, если бы они были доступны в форме заполнения вопроса... почему то администрация не заботиться о том, что выходят новые версии ОС и RAD-ов.


Palladin   (2009-07-06 19:35:00) [25]

а никого не должны волновать основные условия вопрошающего ) их только лузеры не знают )


clickmaker   (2009-07-06 19:27:00) [26]

> delphi 2009 неправильно передает указатель на массив

а где в вопросе звучало delphi 2009?
там, вообще-то, char - уникодный


Германн   (2009-07-04 01:20:00) [27]


> smirnoff ©   (03.07.09 22:22) [17]
>
> всем спасибо за участие. проблема решена. нужно было компилировать
> в delphi 7. (delphi 2009 неправильно передает указатель
> на массив)
>

Опять Дельфи виновато.
:)


smirnoff   (2009-07-03 22:22:00) [28]

всем спасибо за участие. проблема решена. нужно было компилировать в delphi 7. (delphi 2009 неправильно передает указатель на массив)

function func1(input: pchar; output: pchar): bool;  cdecl;
external 'my.dll' name '_func1';

procedure TForm1.Button1Click(Sender: TObject);
var
 a: array[0..40] of char;
 b: pchar;
begin
 a := 'drtj2sdasdasdasd';
 b := @a;
 func1(b,b);
end;


smirnoff   (2009-07-03 20:54:00) [29]


> А отладчик для чего придуман ? Чтобы умные дяди на форуме
> откомпилировали ненужную им DLL и поотлаживали ?

кто не знает ответа - просьба не захламлять тему.
просто объясните как правильно передать указатель на массив в dll файл. статью какую-нибудь подкиньте, я инет перегуглил и ничего полезного для решения проблемы не нашел.


Игорь Шевченко   (2009-07-03 20:38:00) [30]

А отладчик для чего придуман ? Чтобы умные дяди на форуме откомпилировали ненужную им DLL и поотлаживали ?


smirnoff   (2009-07-03 16:19:00) [31]

скомпилируйте кто-нибудь smirnoff ©   (03.07.09 15:38) [10]
посмотрите сами что получается.


smirnoff   (2009-07-03 16:17:00) [32]


> Ты сам в этом уверен ?

ага, даже если так написать ничего не меняется:
extern "C" bool __declspec( dllexport )__cdecl func1(unsigned char *input, unsigned char *output);
extern "C" void __declspec( dllexport )__cdecl test();



> Хм, неужели c++ копирует в этом случае содержимое памяти?


> > input = output;

да это не важно. память копировать не будет. вопрос не в этом. вопрос в том, почему мы видим только первый символ массива input при вызове функции из delphi.


Плохиш   (2009-07-03 16:12:00) [33]


> bool func1(unsigned char *input, unsigned char *output)
> {
> ShowMessage((char *)input);
> input = output;
> }
>

Хм, неужели c++ копирует в этом случае содержимое памяти?


Сергей М.   (2009-07-03 15:59:00) [34]


> потомучто так надо


Я вот не уверен, что при умолчании соглашения о вызове в строке

extern "C" bool __declspec( dllexport ) func1(unsigned char *input, unsigned char *output);

билдер использует именно cdecl-соглашение.

Ты сам в этом уверен ?


smirnoff   (2009-07-03 15:38:00) [35]


> с какого перепугу при импорте тобой выбрано соглашение именно
> cdecl

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

Вот для наглядности код DLL:

[CODE]#include <vcl.h>
#include <windows.h>
#pragma hdrstop

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" bool __declspec( dllexport ) func1(unsigned char *input, unsigned char *output);
extern "C" void __declspec( dllexport ) test();

bool func1(unsigned char *input, unsigned char *output)
{
ShowMessage((char *)input);
input = output;
}

void test()
{
unsigned char *input = "test";
func1(input,input);
}[/CODE]

Обращение из Delphi:

[CODE]function func1(input: pointer; output: pointer): bool; cdecl;
external 'my.dll' name '_func1';
procedure test(); cdecl;
external 'my.dll' name '_test';

procedure TForm1.Button1Click(Sender: TObject);
var
 i :integer;
 s : string;
 a: array[0..30000] of char;
 b: ^uchar;

 a2: array[0..60000] of uchar;
 b2: ^uchar;
begin
StrCopy(a, '123456');
test();   //проверка вызова func1 внутри dll
b := @a;
b2 := @a2;
func1(@a,@a2); //вызов func1 из dll
end;[/CODE]

При вызове func1(@a,@a2); видим только символ "1", нужно вывести все содержимое массива.


Сергей М.   (2009-07-03 15:01:00) [36]


> Visual Basic тут не причем


И действительно ни причем.
А ты только "Visual Basic" и увидел там ?
Ты хоть прочитал это ? Вник в прочитанное ?)

Я ж тебе вопрос задал: с какого перепугу при импорте тобой выбрано соглашение именно cdecl? Есть ли этому вразумительное обоснование ?


smirnoff   (2009-07-03 14:51:00) [37]


> А чего это вдруг cdecl ? http://msdn.microsoft.com/ru-ru/library/dt232c9t.
> aspx

Visual Basic тут не причем. работаем по стандартам codegear.


Сергей М.   (2009-07-03 13:59:00) [38]

А чего это вдруг cdecl?

http://msdn.microsoft.com/ru-ru/library/dt232c9t.aspx


smirnoff   (2009-07-03 13:26:00) [39]

а если


> это убратьb := @a; b2 := @a2;


то Delphi ругается на доступ к памяти при вызове func1


smirnoff   (2009-07-03 13:20:00) [40]


> > Передается только нулевой символПервый символ не #00 ли
> случайно?

нет. передается тот, что в Memo1 на первой позиции.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо