0 / 0 / 0
Регистрация: 27.09.2006
Сообщений: 20
1

Запись значения по указателю, переданному в качестве аргумента в функцию

06.07.2016, 12:22. Показов 2053. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет! Помогите плиз с проблемкой, либо скажите что это не реально))

Добавлено через 2 минуты
Есть функция, к примеру:
Delphi
1
2
3
function GetStr(buf:PCHAR; size:longint; data:pointer):integer;
begin
end;
Первым параметром передается указатель на Char, каким образом можно записать по этому адресу какие-либо данные чаровские, чтобы не было ошибки доступа по памяти, или это сделать не реально?

Заранее спасибо!

Добавлено через 3 минуты
Всеми способами, до которых я додумался, выдают ошибку.

К примеру вот на Сях, как утверждает мой друг и у него все работает, это выглядит следующим образом:
C++
1
2
3
4
5
6
7
int GetStr(char *buf, int *size, void*  userdata)
{
char * data = (char*)userdata;
int len = strlen(data);
while (len-- > 0)
 buf++ = data++;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.07.2016, 12:22
Ответы с готовыми решениями:

Выделить память по указателю, переданному в функцию
Приветствую. У меня тут появился небольшой вопрос... как выделить память по ссылке переданной...

Создать функцию, имеющую два аргумента и возвращающую в качестве аргумента число из отрезка [a,b]
Создать функцию, которая будет иметь два целочисленных параметра a и b, и в качестве своего...

Передача аргумента в функцию а не по указателю
Доброе время суток помогите разобраться как сделать задача: Написать функцию, которая удаляет...

Передача аргумента в функцию по значению, по ссылке, по указателю: в чём концептуальная разница?
Доброго всем здравия, прошу прощения, что достал уже всех этой темой. #include <iostream> using...

5
5782 / 4524 / 1431
Регистрация: 14.04.2014
Сообщений: 20,151
Записей в блоге: 20
06.07.2016, 14:27 2
Нет никакой ошибки "по памяти"
buf - это указатель
выделите память, передайте указатель на нее через buf

кроме того, data - это указатель на что? если на char, то проще и data сделать pchar
как собственно и делается в первой строке на C

кроме того есть просто Move StrCopy и другие
1
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
06.07.2016, 15:06 3
Да, есть уже готовые функции для копирования различных типов строк (String, PChar и т. д.) и для копирования участков памяти - krapotkin об этом уже упомянул.
В дополнение, в контексте кода из заглавного поста темы приведу пример, как можно действовать с нуль-терминальными строками.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//Указатели типа PChar особенным образом сопровождаются компилятором, это позволяет
//обращаться к символам нуль-терминальной строки, как к элементам массива.
//Индексация элементов начинается от нуля.
procedure GetStr(Buf : PChar; Size : Integer; PData : Pointer);
var
  i : Integer;
begin
  for i := 0 to Size - 1 do
    Buf[i] := PChar(PData)[i];
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  PData : String; //Переменная типа String - это указатель на область памяти, в которой расположен текст строки.
  PCh : PChar;
  Size : Integer;
begin
  //Исходные данные.
  PData := '0123456789';
 
  //Количество символов, которые должны быть скопированы из исходных данных.
  Size := 5;
  //Выделяем память для нуль-терминальной строки. +1 - учитываем место для терминального нуля.
  PCh := StrAlloc(Size + 1);
  try
    //Запись терминального нуля.
    //Указатели типа PChar особенным образом сопровождаются компилятором, это позволяет
    //обращаться к символам нуль-терминальной строки, как к элементам массива.
    //Индексация элементов начинается от нуля.
    PCh[Size] := #0;
 
    //Вызов процедуры.
    GetStr(PCh, Size, Pointer(PData));
 
    //Распечатка результирующего текста.
    ShowMessage(PCh); //Будет напечатано: '01234'.
  finally
    //Освобождение памяти, выделенной для нуль-терминальной строки.
    //StrDispose() применяется только, если память выделялась через вызов StrAlloc().
    StrDispose(PCh);
  end;
end;
0
0 / 0 / 0
Регистрация: 27.09.2006
Сообщений: 20
07.07.2016, 19:52  [ТС] 4
Mawrat, krapotkin, спасибо за ответ!!

Но при подходе Mawrat все таки возникает ошибка Access Violation, так как у вас предварительно выделяется память под указатель:

Delphi
1
PCh := StrAlloc(Size + 1);
А мне надо без выделения памяти, просто по адресу записать значение. Поясню вообще для чего всё это нужно, эта функция GetStr устанавливается как callback для dll'ки, то есть я пишу в ней код, который выполнится в какой то момент работы dll, и dll получит данные по указателю buf. На мой взгляд это извращение, но функция в зависимости от того какая инфа передается в PData ведет себя по разному, то есть я могу контролировать работу одной из функций dll в зависимости от того что мне надо. Ну вот так реализовали разработчики dll. У них все на сях.

Добавлено через 46 минут
А да, забыл сказать, среда разработки Delphi6))
0
438 / 367 / 132
Регистрация: 09.09.2011
Сообщений: 1,334
08.07.2016, 00:12 5
KerLaeda, вам же уже все написали в сообщении krapotkin. используйте move и не полоскайте мозг.

у вас в программе есть userdata - массив char-ов c \0 в конце (если судить по коду на Си). userdata - может быть и в динамической памяти и на стеке и даже константой в сегменте данных, просто сделайте move из userdata в buf и не забудьте в size записать количество передаваемых байтов. кстати максимальный размер буфера должен быть где-то в константах быть.

кроме того у вас не правильно прототип функции указан - не так как на СИ, должно быть вот так:
Delphi
1
function GetStr(buf:PCHAR; size:Plongint; data:pointer):integer;
кроме того, если код 32-битный и dll на СИ написана - то нужно еще указать правильное соглашение о вызовах, тут скорее всего cdecl,

т.е. такой прототип должен быть:
Delphi
1
function GetStr(buf:PCHAR; size:Plongint; data:pointer):integer; cdecl;
Добавлено через 3 минуты
блин, вы же пишете что delphi 6 - значит 100% 32 битный код. Ваш Access Violation из-за не верного соглашения о вызовах - в delpi и СИ они разные (по умолчанию).
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
08.07.2016, 08:03 6
Цитата Сообщение от KerLaeda Посмотреть сообщение
Но при подходе Mawrat все таки возникает ошибка Access Violation, так как у вас предварительно выделяется память под указатель:
Этот код без ошибок отрабатывает. Наверное, имеется в виду, что есть некоторый адаптированный код, написанный по мотивам моего - вот при его выполнении ошибка возникает, как я понимаю. И, как сказал Kitayets, соглашение о вызовах надо учесть.
Цитата Сообщение от KerLaeda Посмотреть сообщение
А мне надо без выделения памяти, просто по адресу записать значение.
Это как понимать? Чтобы по какому-то адресу записать значение, предварительно по этому адресу должна быть выделена память - статическая (перед запуском программы) или динамическая. Если этого не сделать, при попытке записи получим исключение Access Violation либо повреждение данных.
Цитата Сообщение от KerLaeda Посмотреть сообщение
Поясню вообще для чего всё это нужно, эта функция GetStr устанавливается как callback для dll'ки, то есть я пишу в ней код, который выполнится в какой то момент работы dll, и dll получит данные по указателю buf.
Так надо, значит, прочитать данные, которые расположены по какому-то адресу (из buf) и записать в какую-то переменную, определённую в функции из dll? KerLaeda, опиши более подробно - что нужно сделать?
0
08.07.2016, 08:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.07.2016, 08:03
Помогаю со студенческими работами здесь

Как создать функцию, принимающую в качестве аргумента иную функцию, в которой есть параметры по умолчанию?
У меня имеется функция msk с параметрами по умолчанию double msk(double a = 0.0, double b = 1.0) И...

Как передать функцию в качестве аргумента?
Как передать функцию в функцию, выполняющую усреднение значения через интегрирование. Так как...

Функция, которая принимает в качестве аргумента функцию
Вам уже приходилось писать таблицу умножения. Но на этот раз вас попросили сделать в плюс к таблице...

Как передать функции указатель на функцию в качестве аргумента?
как передать функции указатель на функцию в качестве аргумента?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru