void DLL_EXPORT write_res(char *s)
{
MessageBoxA(0, s, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
Передача строки delphi в dll написаной на c++
...опишу что уже пробовал:
Есть программа на делфи
Код:
procedure someFunc(str : {тут пробовал пихать и стринг и указатель}); stdcall; external 'lib.dll' //внешняя процедура в длл
Ну и разумеется dll на С++ *.h
Код:
void DLL_EXPORT someFunc(char *s);
в нете много похожих тем, но я не увидел подходящего решения;
понял что в делфи и си работа с памятью идёт наоборот, думаю это исправил stdcall ;
пробовал посылать в dllуказатель на строку, как это любит С, но толку не увидел;
ещё думаю что проблема в string так ка он 4 байта весит а в С 1;
помогите разобраться, я уже запутался окончательно...
ANSIString пихали али что?
PCHAR
Тип String: по смещению -4 храниться длина строки, а по смещению -8 храниться счётчик ссылок на строку (когда он обнуляется то строка уничтожается) Сама строка располагается в памяти как есть (каждая буква занимает 1 байт).При копировании строки (s1:= s2;) реального копирования не происходит, увеличивается только счётчик ссылок, но если после этого изменить одну из строк, (s1:= s1 + 'a';) то произойдёт физическое копирование содержимого строк, и теперь s1 и s2 будут показывать на разные адреса в памяти.
Примечание Fantasist'a: Это верно только если s1 - локальная переменная, или s1 и s2 - обе не локальные. Если s1 не локальная (т.е. глобальная или член класса), а s2 - локальная то происходит копирование.
Тип PChar - длина строки определяется от начала до #0 байта, по сути это чистой воды pointer, так что все действия по отслеживанию распределения памяти лежат на программисте - сами заботьтесь о том чтобы хватило места для распределения памяти и освобождении после использования. Тоже одна буква = 1 байт Для хранения unicode (т.е. 2х байтовых символов) используйте соответствующие символы с приставкой Wide... ©Drkb::00135 (Взято с Vingrad.ru)
Соглашения об вызовах и преобразованиях типов обычно способны разрешить конфликты и несовместимость между C++ и PASCAL. Хороший ресурс по вопросам совместимости между Delphi и C++ расположен на сайте Borland.
Я смотрел через sizeof(string) в делфи, то мне выдаёт 4 байта, тоисть как я понимаю это масив элементов по 4 байта,
по вашим словам, как я понял, мне надо будет в Си сместится в моём char *str на 8 байт, где и будетсама строка, так?
Но почему же когда я выводил строку через API MessageBox в длл, то мне не вывело мою строку, а непонятный набор символов, ведь конец файла это '\0' ?
Надо разобраться с типами в C++ и Delphi,чтоб понять,как правильно писать
Я передаю PChar в функцию Си
Код:
В боксе я вижу первую букву, значит следующая - нуль.
Походу делфи дает Си указатель на копию символа, так как даже PString не помог. И сразу после уведомления месыджбокса идёт acces volation, тоисть С++ пробует найти конец строки, а система ему говорит: "не твоё не лезь".
Идеи ещё есть?
Код:
procedure write_res(s : PString) stdcall; external 'lib.dll';
procedure TForm1.Button1Click(Sender: TObject);
var s : PString; str : ShortString;
begin
str:=Edit1.Text;
str[Length(str)+1]:=#00;
s:=@str[1];
write_res(s);
end;
procedure TForm1.Button1Click(Sender: TObject);
var s : PString; str : ShortString;
begin
str:=Edit1.Text;
str[Length(str)+1]:=#00;
s:=@str[1];
write_res(s);
end;
Идёт передача указателя на начоло самой строки, и обнуление в конце для того чтобы не было acces volation
Всем большое спасибо спасибо, тему можно закрыть.:D
Alegun, емнип в современных string одна буква - два байта, не? Юникод же замутили.
А, ну ок. Надо бы в правилах написать, чтобы версию уже указывали вопрошающие.
Цитата: napalm256
Идёт передача указателя на начоло самой строки, и обнуление в конце для того чтобы не было acces volation
Всем большое спасибо спасибо, тему можно закрыть.:D
Вообще String в делфи таков, что в конце у него находится нуль-символ (и потому конвертация его в PChar тривиальна). Тип PChar специально нужен для интеропа с Сишным кодом, почему бы не использовать его?
Код:
procedure write_res(s : PChar) stdcall; external 'lib.dll';
procedure TForm1.Button1Click(Sender: TObject);
begin
write_res(PChar(Edit1.Text));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
write_res(PChar(Edit1.Text));
end;