2012-02-15 2 views
4

Может ли кто-нибудь предоставить мне рабочий пример прохождения произвольного количества байтов через параметр в функцию dll?Передача двоичных данных в dll-функцию в D7

Я хотел бы сделать это без дополнительного блока памяти, просто работать только с основными типами окон.

Мне нужно «отправить» около 300 кб данных за каждый звонок.

Должно ли выделенное на стороне клиента освобождение памяти также на стороне клиента?

функция
+0

мы бы хотели, но мы хотим увидеть, что вы что-то пробовали ... – ComputerSaysNo

+2

О распределении и освобождении: либо делать как на стороне вызывающего абонента, так и на стороне вызываемого абонента. Поэтому, если вы хотите выделить его на стороне клиента, освободите его и на стороне клиента. –

ответ

7

DLL, должна выглядеть следующим образом:

procedure Test(Buffer: Pointer; Length: Integer); stdcall; 
begin 
    //Buffer points to the start of the buffer. 
    //The Buffer size if Length bytes. 
end; 

Предполагая, что вы вызываете его из другого модуля Delphi вызов может выглядеть следующим образом:

procedure Test(Buffer: Pointer; Length: Integer); stdcall; external 'test.dll'; 

procedure CallTest; 
var 
    Buffer: array of Byte; 
begin 
    SetLength(Buffer, 1000); 
    //populate Buffer 
    Test(@Buffer[0], Length(Buffer)); 
end; 

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

Приведенный выше пример выделяет и освобождает его в модуле вызывающего абонента. Это означает, что метод Test должен либо полностью обработать Buffer, прежде чем возвращать, либо взять копию содержимого Buffer перед возвратом.

Теперь, хотя есть возможность распределения и освобождения в модуле вызываемого абонента, это реже. Это реже, потому что обычно это менее удобно делать так. Он часто влечет за собой больше функций API или, возможно, более сложный интерфейс. Вы будете перенаправлены на маршрут распределения вызываемого абонента, когда вызывающий абонент не сможет определить соответствующий размер для буфера.

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

+3

Вы ничего не сказали об освобождении: поскольку 'Buffer' - это динамический массив, он будет освобожден, когда останется' CallTest'. Поэтому DLL должна сделать свою собственную копию, если она намерена хранить данные после вызова 'Test'. –

+0

@ JensMühlenhoff Совершенно верно. Благодарю. Добавлен комментарий. –

+0

Я думаю, что распределение модулей должно выполняться, когда вы * возвращаете * буфер из функции модуля, а затем освобождаете его в функции вызывающего абонента (например, 'LocalAlloc' в модуле и' LocalFree' в вызывающем абоненте). – kobik

Смежные вопросы