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

Вниз

Обращение из Delphi к DLL написанной на C++   Найти похожие ветки 

 
smirnoff ©   (2009-07-03 12:02) [0]

Здравствуйте! У меня вопрос по работе с типом 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. Заранее огромное спасибо!


 
Плохиш ©   (2009-07-03 12:23) [1]


> func1(b,b2);

func1(PChar(a), PChar(a2));

Это что ли надо?


 
smirnoff ©   (2009-07-03 12:42) [2]


> func1(PChar(a), PChar(a2));Это что ли надо?


Пробовал, эффект то же, что и прежде. Передается только нулевой символ,  хотелось бы чтобы весь массив был доступен для dll.


 
clickmaker ©   (2009-07-03 12:59) [3]

a: array[0..30000] of char;
b: PChar absolute a;

a2: array[0..60000] of uchar;
b2: PChar absolute a2;

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


 
Плохиш ©   (2009-07-03 12:59) [4]


> Передается только нулевой символ

Первый символ не #00 ли случайно?


 
smirnoff ©   (2009-07-03 13:20) [5]


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

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


 
smirnoff ©   (2009-07-03 13:26) [6]

а если


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


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


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

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

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


 
smirnoff ©   (2009-07-03 14:51) [8]


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

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


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


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


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

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


 
smirnoff ©   (2009-07-03 15:38) [10]


> с какого перепугу при импорте тобой выбрано соглашение именно
> 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:59) [11]


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


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

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

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

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


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


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

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


 
smirnoff ©   (2009-07-03 16:17) [13]


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

ага, даже если так написать ничего не меняется:
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.


 
smirnoff ©   (2009-07-03 16:19) [14]

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


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

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


 
smirnoff ©   (2009-07-03 20:54) [16]


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

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


 
smirnoff ©   (2009-07-03 22:22) [17]

всем спасибо за участие. проблема решена. нужно было компилировать в 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;


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


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

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


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

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

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


 
Palladin ©   (2009-07-06 19:35) [20]

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


 
smirnoff ©   (2009-07-06 19:51) [21]

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


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


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


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


 
KSergey ©   (2009-07-10 10:39) [23]

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

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


 
KSergey ©   (2009-07-10 10:44) [24]

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

> 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:46) [25]

> KSergey ©   (10.07.09 10:44) [24]
> тогда все будет хорошо

Это, разумеется, не мантра, т.е. объяснение "почему" - очень даже есть, надо просто посмотреть чем отличается bool и BOOL в С++.


 
Пит   (2009-07-10 17:44) [26]


> ergey ©   (10.07.09 10:44) [24]

а вот это меня уже заинтересовало.

bool в дельфи это 4-ех байтовый. boolean - однобайтовый.

BOOL в Си я так понимаю ты имеешь в виду четырехбайтовый. А что же такое bool в Си?


 
KSergey ©   (2009-07-12 13:02) [27]

> Пит   (10.07.09 17:44) [26]
>  А что же такое bool в Си?

В Си нету bool. А вот в С++ - есть. В книжках все написано :)
http://msdn.microsoft.com/en-us/library/tf4dy80a(VS.71,loband).aspx

А BOOL в С++ для виндовс - это вообще define. Про другие ОС не в курсе.


 
icWasya ©   (2009-07-13 10:39) [28]

И всё-таки __declspec( dllexport ) - это stdcall.
Может быть и скомпилируется с cdecl, но порядок параметров будет другой. Потом будете сильно удивлятся.


 
Anatoly Podgoretsky ©   (2009-07-13 11:55) [29]


> icWasya ©   (13.07.09 10:39) [28]

Не стоит фантазировать насчет порядка.


 
Пит   (2009-07-13 11:58) [30]


> В Си нету bool. А вот в С++ - есть. В книжках все написано
> :)

это все здорово. Но вернемся к баранам.
Ты сказал:

bool в дельфи и bool в C++ - сильно очень разное

bool в дельфи это 4-ех байтовый флаг, LongBool. Ноль интерпретируется как false, все отличное от нуля как true.

По твоим словам в С++ это нечно сильно другое. Я и хотел узнать - в чем отличие?


 
clickmaker ©   (2009-07-13 12:12) [31]

> в чем отличие?

в MS VC это может быть и 4 и 1 байт. В билдере - не в курсе. Но подозреваю, что если VCL у них общая, то должна быть совместимость типов


 
KSergey ©   (2009-07-13 14:50) [32]

> clickmaker ©   (13.07.09 12:12) [31]
> в MS VC ... . В билдере - не в курсе.
>  Но подозреваю, что если VCL у них общая,

???!!!


 
KSergey ©   (2009-07-13 14:51) [33]

я их как раз недавно пытался на "общую" VCL "пересадить" - спасибо что Дуп вовремя отговорил от ереси и уберег от согрешения.


 
Anatoly Podgoretsky ©   (2009-07-13 15:55) [34]

общая с Дельфи, по контесту с предыдущими сообщениями.


 
clickmaker ©   (2009-07-13 17:01) [35]

> [32] KSergey ©   (13.07.09 14:50)

ну конечно, я имел в виду, что билдер пользуется дельфовой vcl, которая на паскале написана, как известно )


 
KSergey ©   (2009-07-14 08:32) [36]

Ну тогда и я уточню:

> KSergey ©   (13.07.09 14:51) [33]
> я их как раз недавно пытался на "общую" VCL "пересадить"

"их" - MS VC++ и Delphi


 
Пит   (2009-07-14 12:19) [37]

KSergey, так ты можешь в конце концов пояснить свою точку зрения?

Чем bool в С++ так сильно отличается от bool в дельфи?


 
Anatoly Podgoretsky ©   (2009-07-14 12:31) [38]

bool <> BOOL


 
KSergey ©   (2009-07-16 08:19) [39]

> Пит   (14.07.09 12:19) [37]
> Чем bool в С++ так сильно отличается от bool в дельфи?

Я уже давал ссылку, в разделе "Microsoft Specific" там все подробно расписано про С++.
Про регистронечувтсвительность одного и чувтсвительность другого я тоже вроде вполне определенно писал.
Что именно еще непонятно?


 
Пит   (2009-07-16 12:28) [40]

Непонятно, что конкретно ты хотел сказать.
Ну если лень писать - тогда попишу я, не привыкать )))

Ты хотел сказать, что в VC++ до версии 5.0 bool был 4-ех байтовым, начиная с пятой стал однобайтовым.
BOOL везде 4-ех байтовый.

В дельфи же bool 4-ех байтовый, а boolean однобайтовый.

Правильно я понял?



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

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

Наверх




Память: 0.57 MB
Время: 0.03 c
15-1263251045
Smile
2010-01-12 02:04
2010.04.04
Германн или где?


3-1237759093
zod33
2009-03-23 00:58
2010.04.04
Ошибка при вставке


11-1214986969
Nikfel
2008-07-02 12:22
2010.04.04
Как работать с компонентом TKolSAComboBoxEx.


6-1216320126
alexda
2008-07-17 22:42
2010.04.04
Socket Error


3-1237815167
victor
2009-03-23 16:32
2010.04.04
PickList