![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обращение из Delphi к DLL написанной на C++ [D7, WinXP]
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 на первой позиции.